从辅助函数更新DOM后运行函数

时间:2015-07-11 03:27:55

标签: javascript meteor

修改

这正是我想要做的事情:

  Template.FrameItems.helpers({
    frames: function() {
      var trialId = Session.get('trialId');
      return Frames.find({trialId: trialId});
      // when new frames are rendered, I want to call positionElements()
    }
  });

  Template.FrameItems.onRendered(function() {
    this.autorun(function() {
      var trialId = Session.get("trialId");
      positionElements();
      // problem: positionElements() is called before the DOM is updated from `frames` helper function
    })
  });

EDIT2:

这是我的第二次尝试无效。

  var frameDep = new Tracker.Dependency;
  Template.FrameItems.helpers({
    frames: function() {
      var trialId = Session.get('trialId');
      frameDep.changed();
      return Frames.find({trialId: trialId});
      // when new frames are rendered, I want to call positionElements()
    }
  });

  Template.FrameItems.onRendered(function() {
    this.autorun(function() {
      frameDep.depend();
      positionElements();
    });

同样的问题仍然存在。在调用positionElements()时,DOM仍未使用新的frames对象进行更新。我需要一种方法来找出更新DOM的时间。在第一次呈现模板后不会调用onRendered(),这在我的情况下是有问题的。

EDIT3:

我最终做到了这一点,但我觉得应该有一个更好的解决方案。

if (Meteor.isClient) {
  var frameItemsTemplate;
  Template.TrialWorkSpace.onRendered(function() {
    this.autorun(function() {
      var trialId = Session.get("trialId");
      if (frameItemsTemplate) {
        Blaze.remove(frameItemsTemplate);
      }
      frameItemsTemplate = Blaze.render(Template.FrameItems,
        $('.frame-items-container')[0]);
    });
  });

  Template.FrameItems.helpers({
    frames: function() {
      var trialId = Session.get('trialId');
      return Frames.find({trialId: trialId});
    }
  });

  Template.FrameItems.onRendered(function() {
    positionElements();
  });
}

模板文件

<template name="TrialWorkSpace">
  <div class="trial-workspace-container">  
    <div class="row frame-items-container">
      <!-- populated programmatically instead of {{> FrameItems}} -->
    </div>
  </div>
</template>

<template name="FrameItems">
  {{#each frames}}
    <div id="frame-{{_id}}" class="frame-preview-item cyan lighten-5">
      <div class='frame-name'>{{name}}</div>
      <div class="ep"></div>
    </div>
  {{/each}}
</template>

2 个答案:

答案 0 :(得分:1)

你的第一个假设是错误的。 onRendered仅在将模板插入DOM时呈现,如果您想要反馈,则您希望在回调中粘贴autorun

if (Meteor.isClient) {
  Template.TrialWorkSpace.onCreated({
    dep = new Tracker.Dependency();
  });
  Template.FrameItems.helpers({
    frames: function() {
      var trialId = Session.get('trialId');
      console.log("I am getting called");
      dep.changed();
      return Frames.find({trialId: trialId});
    }
  });

  Template.TrialWorkSpace.onRendered(function() {
    Tracker.autorun(function() {
      dep.depend();
      console.log("onRendered");
    })
  })
}

答案 1 :(得分:0)

我已经解决了以下问题:

Template.TrialWorkSpace.onRendered(function() {
    var self = this;
    self.autorun(function(){
        var trialId = Session.get("trialId");
        Tracker.afterflush(function(){
           positionElements();
        }.bind(self));
    })
});

设置或更改Session.get("trialId")时,在dom刷新后调用positionElements()