【问题标题】:Meteor: How to make Bootstrap Select reactive?Meteor:如何使 Bootstrap Select 具有反应性?
【发布时间】:2016-02-26 05:02:10
【问题描述】:

当使用 Bootstrap 多选时,我发现多选 jquery 总是有点过早触发 - 在模板完成从助手中提取数据之前,因此选择框通常是空的(我会说大约 60 % 的时间)。

显然 Template.usersLayout.rendered() 不是调用依赖于已呈现数据的函数的正确位置。有什么更好的方法来做到这一点?

另外,我猜让 bootstrap-select javascript 'reactive 将是一等奖。我该怎么做?

代码如下

===========

我正在使用帮助器 (#each) 创建一个选择框,其中每个选项都是它自己的数据上下文。

<template name="usersLayout">
    <form>
        <!-- Multiselect for instruments -->
        <div class="form-group">
            <label for="playerInstruments">Player instruments</label>
            <div class="controls text-left">
                <select id="playerInstruments" multiple="multiple" class="selectFilter" name="playerInstruments">
                    {{#each instruments}}
                    <option value="{{name}}">{{name}}</option>
                    {{/each}}
                </select>
            </div>
        </div>
    </form>
</template>

helper 定义如下:

Template.usersLayout.helpers({

    /* Database retrievals */

    // Returns all Instruments from Mongo
    instruments: function() {
        return Instruments.find();
    }

})

twitter 引导代码如下所示:

Template.usersLayout.rendered = function () {

    $('#playerInstruments').multiselect({
        disableIfEmpty: true,
        onChange: function(option, checked) {
            // Set the session as the checked valuess
            var tempSessionArr = $("#playerInstruments").val();
            // Add or delete from Session
            Session.set('playerInstruments', tempSessionArr);
        },
    });
}

【问题讨论】:

  • 您是如何订阅数据的?在路由器上?你能告诉我们订阅代码吗?
  • 不,我还没有订阅。我还没有添加需要订阅的安全设置(我认为)。但这是我的第一个流星应用程序,如果这没有意义,请纠正我。
  • 我正在使用 flow-router,顺便说一下,在加载具有其他引导选择要求的新页面时会导致问题

标签: twitter-bootstrap meteor bootstrap-select


【解决方案1】:

问题是您的模板在开始渲染之前没有等待数据,由于数据仅在模板已经渲染后出现在页面上,因此选择框为空。我知道这是您的第一个应用程序,您没有删除 autopublish 包,但最好遵循 Flow Router 的完整教程

首先,阅读this。然后,将您的路由器更改为具有subcriptions 选项。之后,通过thissubsReady() 应该在rendered 函数内)检查订阅是否准备就绪,然后在subsReady()callback 中,初始化选择框

【讨论】:

  • 我假设您的意思是 Tracker.subsReady(),而不是 Tracker.subReady()?
  • 我的意思是流路由器的 subsReady
【解决方案2】:

您想使用template events 来捕获更改事件,而不是设置 jQuery 挂钩。

Template.usersLayout.events({
  '#playerInstruments change': function(ev){
    var tempSessionArr = $("#playerInstruments").val();
    Session.set('playerInstruments', tempSessionArr);
  },
});

然后将您的multiselect 设置保留在onRendered 处理程序中:

Template.usersLayout.rendered = function () {
  $('#playerInstruments').multiselect({ disableIfEmpty: true });
};

如果这仍然不起作用,请尝试使用 defer 包装后者:

Template.usersLayout.rendered = function () {
  Meteor.defer(function(){
    $('#playerInstruments').multiselect({ disableIfEmpty: true });
  });
};

【讨论】:

  • 不,我不认为这会起作用,因为我不能调用 multiselect() 函数?
  • 这很 hacky... Meteor.defer 似乎等同于 setTimeout(),这实际上意味着我会“希望”在我运行 multiselect() 时填充选择框.不能保证这一点 - 它“可能”会起作用,除非它不起作用。
  • @Thai 是正确的,如果您在呈现此模板时未加载订阅,那么在数据可用之前,{{#each}} 将不会运行。因此,从反应性 pov 中,模板被渲染,但您的多选中没有任何内容。您没有在任何地方提及您的订阅,但这是一个很好的地方。 Meteor.defer() 在您希望在 js 运行之前允许绘制待处理的 UI 更改时很有帮助。
猜你喜欢
  • 2014-10-18
  • 1970-01-01
  • 1970-01-01
  • 2015-07-18
  • 1970-01-01
  • 1970-01-01
  • 2014-05-18
  • 2016-08-29
  • 1970-01-01
相关资源
最近更新 更多