瀏覽代碼

Fix the board component data loading

Maxime Quandalle 9 年之前
父節點
當前提交
2248671b7c

+ 2 - 2
client/components/activities/activities.js

@@ -55,7 +55,7 @@ BlazeComponent.extendComponent({
 
   cardLink: function() {
     var card = this.currentData().card();
-    return Blaze.toHTML(HTML.A({
+    return card && Blaze.toHTML(HTML.A({
       href: card.absoluteUrl(),
       'class': 'action-card'
     }, card.title));
@@ -69,7 +69,7 @@ BlazeComponent.extendComponent({
 
   attachmentLink: function() {
     var attachment = this.currentData().attachment();
-    return Blaze.toHTML(HTML.A({
+    return attachment && Blaze.toHTML(HTML.A({
       href: attachment.url(),
       'class': 'js-open-attachment-viewer'
     }, attachment.name()));

+ 19 - 16
client/components/boards/boardBody.jade

@@ -1,26 +1,29 @@
 template(name="board")
-  if Template.subscriptionsReady
+  if isBoardReady.get
     if currentBoard
-      .board-wrapper(class=currentBoard.colorClass)
-        .board-canvas(
-          class=currentBoard.sidebarSize
-          class="{{#if MultiSelection.isActive}}is-multiselection-active{{/if}}"
-          class="{{#if draggingActive.get}}is-dragging-active{{/if}}")
-          if showOverlay.get
-            .board-overlay
-          .lists.js-lists
-            each currentBoard.lists
-              +list(this)
-              if currentCardIsInThisList
-                +cardDetails(currentCard)
-            if currentUser.isBoardMember
-              +addListForm
-        +sidebar
+      +boardBody
     else
       +message(label="board-no-found")
   else
     +spinner
 
+template(name="boardBody")
+  .board-wrapper(class=currentBoard.colorClass)
+    .board-canvas(
+      class=currentBoard.sidebarSize
+      class="{{#if MultiSelection.isActive}}is-multiselection-active{{/if}}"
+      class="{{#if draggingActive.get}}is-dragging-active{{/if}}")
+      if showOverlay.get
+        .board-overlay
+      .lists.js-lists
+        each currentBoard.lists
+          +list(this)
+          if currentCardIsInThisList
+            +cardDetails(currentCard)
+        if currentUser.isBoardMember
+          +addListForm
+    +sidebar
+
 template(name="addListForm")
   .list.js-list.list-composer.js-list-composer
     +inlinedForm(autoclose=false)

+ 77 - 70
client/components/boards/boardBody.js

@@ -1,4 +1,4 @@
-var boardSubsManager = new SubsManager();
+var subManager = new SubsManager();
 
 BlazeComponent.extendComponent({
   template: function() {
@@ -6,12 +6,19 @@ BlazeComponent.extendComponent({
   },
 
   onCreated: function() {
-    this.draggingActive = new ReactiveVar(false);
-    this.showOverlay = new ReactiveVar(false);
+    var self = this;
+    self.draggingActive = new ReactiveVar(false);
+    self.showOverlay = new ReactiveVar(false);
+    self.isBoardReady = new ReactiveVar(false);
 
+    // The pattern we use to manually handle data loading is described here:
+    // https://kadira.io/academy/meteor-routing-guide/content/subscriptions-and-data-management/using-subs-manager
     // XXX The boardId should be readed from some sort the component "props",
     // unfortunatly, Blaze doesn't have this notion.
-    boardSubsManager.subscribe('board', Session.get('currentBoard'));
+    self.autorun(function() {
+      var handle = subManager.subscribe('board', Session.get('currentBoard'));
+      self.isBoardReady.set(handle.ready());
+    });
   },
 
   openNewListForm: function() {
@@ -47,72 +54,6 @@ BlazeComponent.extendComponent({
     return currentCard && currentCard.listId === listId;
   },
 
-  onRendered: function() {
-    var self = this;
-
-    self.scrollLeft();
-
-    var lists = this.find('.js-lists');
-
-    // We want to animate the card details window closing. We rely on CSS
-    // transition for the actual animation.
-    lists._uihooks = {
-      removeElement: function(node) {
-        var removeNode = _.once(function() {
-          node.parentNode.removeChild(node);
-        });
-        if ($(node).hasClass('js-card-details')) {
-          $(node).css({
-            flexBasis: 0,
-            padding: 0
-          });
-          $(lists).one(CSSEvents.transitionend, removeNode);
-        } else {
-          removeNode();
-        }
-      }
-    };
-
-    if (! Meteor.user() || ! Meteor.user().isBoardMember())
-      return;
-
-    self.$(lists).sortable({
-      tolerance: 'pointer',
-      helper: 'clone',
-      items: '.js-list:not(.js-list-composer)',
-      placeholder: 'list placeholder',
-      distance: 7,
-      start: function(evt, ui) {
-        ui.placeholder.height(ui.helper.height());
-        Popup.close();
-      },
-      stop: function() {
-        self.$('.js-lists').find('.js-list:not(.js-list-composer)').each(
-          function(i, list) {
-            var data = Blaze.getData(list);
-            Lists.update(data._id, {
-              $set: {
-                sort: i
-              }
-            });
-          }
-        );
-      }
-    });
-
-    // Disable drag-dropping while in multi-selection mode
-    self.autorun(function() {
-      self.$(lists).sortable('option', 'disabled', MultiSelection.isActive());
-    });
-
-    // If there is no data in the board (ie, no lists) we autofocus the list
-    // creation form by clicking on the corresponding element.
-    var currentBoard = Boards.findOne(Session.get('currentBoard'));
-    if (currentBoard.lists().count() === 0) {
-      this.openNewListForm();
-    }
-  },
-
   sidebarSize: function() {
     var sidebar = this.componentChildren('sidebar')[0];
     if (sidebar && sidebar.isOpen())
@@ -130,6 +71,72 @@ BlazeComponent.extendComponent({
   }
 }).register('board');
 
+Template.boardBody.onRendered(function() {
+  var self = BlazeComponent.getComponentForElement(this.firstNode);
+
+  self.scrollLeft();
+
+  var lists = this.find('.js-lists');
+
+  // We want to animate the card details window closing. We rely on CSS
+  // transition for the actual animation.
+  lists._uihooks = {
+    removeElement: function(node) {
+      var removeNode = _.once(function() {
+        node.parentNode.removeChild(node);
+      });
+      if ($(node).hasClass('js-card-details')) {
+        $(node).css({
+          flexBasis: 0,
+          padding: 0
+        });
+        $(lists).one(CSSEvents.transitionend, removeNode);
+      } else {
+        removeNode();
+      }
+    }
+  };
+
+  if (! Meteor.user() || ! Meteor.user().isBoardMember())
+    return;
+
+  self.$(lists).sortable({
+    tolerance: 'pointer',
+    helper: 'clone',
+    items: '.js-list:not(.js-list-composer)',
+    placeholder: 'list placeholder',
+    distance: 7,
+    start: function(evt, ui) {
+      ui.placeholder.height(ui.helper.height());
+      Popup.close();
+    },
+    stop: function() {
+      self.$('.js-lists').find('.js-list:not(.js-list-composer)').each(
+        function(i, list) {
+          var data = Blaze.getData(list);
+          Lists.update(data._id, {
+            $set: {
+              sort: i
+            }
+          });
+        }
+      );
+    }
+  });
+
+  // Disable drag-dropping while in multi-selection mode
+  self.autorun(function() {
+    self.$(lists).sortable('option', 'disabled', MultiSelection.isActive());
+  });
+
+  // If there is no data in the board (ie, no lists) we autofocus the list
+  // creation form by clicking on the corresponding element.
+  var currentBoard = Boards.findOne(Session.get('currentBoard'));
+  if (currentBoard.lists().count() === 0) {
+    self.openNewListForm();
+  }
+});
+
 BlazeComponent.extendComponent({
   template: function() {
     return 'addListForm';