jQuery选择不在Meteor 1.1.0.2 onRendered中工作

时间:2015-07-26 22:02:40

标签: meteor meteor-blaze

我正在开发一个我已部署的应用程序,并尝试将所有内容升级到最新版本并更新代码以利用最新的进程,例如在Template.onRendered中进行订阅,但我似乎已经破坏了我的可排序性

我的模板(稍微简化)

<template name="formEdit">
  <div id="formContainer">
    {{#if Template.subscriptionsReady}}
      {{#with form this}}
        <table id="headerFieldsTable" class="table">
          <tbody id="headerFields">
            {{#each headerFields}}
              <tr class="headerFieldRow">
                <td>{{> headerFieldViewRow }}</td>
              </tr>
            {{/each}}
          </tbody>
        </table>

        <h5>Form Fields</h5>
        <table id="formFieldsTable" class="table">
          <tbody id="formFields">
            {{#each formFields}}
              <tr class="formFieldRow">
                <td>{{> formFieldViewRow }}</td>
              </tr>
            {{/each}}
          </tbody>
        </table>

      {{/with}}
    {{else}}
      Loading...
    {{/if}}
  </div>
</template>

模板的onRendered():

Template.formEdit.onRendered(function() {
  var formsSubscription = this.subscribe('formById', this.data);
  var headerFieldsSubscription = this.subscribe('headerFieldsForForm', this.data);
  var formFieldsSubscription = this.subscribe('formFieldsForForm', this.data);

  var formEditTemplate = this;
  this.autorun(function() {
    if (formsSubscription.ready() && headerFieldsSubscription.ready() && formFieldsSubscription.ready()) {
formEditTemplate.$(''));
      formEditTemplate.$('#headerFields').sortable({
        axis: "y",
        stop: function(event, ui) {
          var headersToSave = [];
          $('#headerFieldsTable div.headerField').each(function(idx, headerFieldDiv) {
            var header = Blaze.getData(headerFieldDiv);
            header.sequence = idx;
            headersToSave.push(header);
          });
          _.each(headersToSave, function(header) { header.save(); });
        }
      });

      formEditTemplate.$('#formFields').sortable({
        axis: "y",
        stop: function(event, ui) {
          var feildsToSave = [];
          $('#formFieldsTable div.formField').each(function(idx, formFieldDiv) {
            var field = Blaze.getData(formFieldDiv);
            field.sequence = idx;
            feildsToSave.push(field);
          });
          _.each(feildsToSave, function(field) { field.save(); });
        }
      });
    }
  });
});

但对于页眉和页脚,formEditTemplate.$('#headerFields')formEditTemplate.$('#formFields')似乎都没有返回任何结果。似乎DOM实际上并不存在。我认为对所有订阅的.ready()调用会纠正这一点,但是认为Blaze还没有修复DOM的时间问题,但订阅确实完成了。我这样说是因为我在if的第一行放了一个断点,浏览器仍在显示&#34;正在加载...&#34;。

我还尝试通过一个帮助程序来热线连接事物,该帮助器设置放置在{{#with}}块末尾的可排序项,希望它可能会最后呈现,但是它没有工作

我在Meteor论坛上发现了一些似乎建议添加计时器的文章,但这似乎非常&#34; hackish&#34;。是否有一个新的模式来运行JS,需要完全初始化DOM?

1 个答案:

答案 0 :(得分:3)

我建议您使用Tracker.afterFlush()来保证已创建和更新DOM,而不是延迟时间。以下是Meteor docs的说明:

  

计划在下一次刷新期间或之后调用的函数   所有无效后,当前正在进行刷新   计算已重新运行。该功能将运行一次而不是运行   除非再次调用afterFlush,否则后续刷新。

因此,在if语句中,您可以像这样包装代码块

if (formsSubscription.ready() && headerFieldsSubscription.ready() && formFieldsSubscription.ready()) {
  Tracker.afterFlush( function () {
    //Code block to be executed after subscriptions ready AND DOM updated
  });
}

Here是使用Tracker.afterFlush的示例的参考。