4

我有以下模板:

<template name="modalTest">
    {{session "modalTestNumber"}} <button id="modalTestIncrement">Increment</button>
</template>

session助手只是Session对象的中间人。我已将其modalTestNumber初始化为0.

我希望这个模板以其所有的反应性呈现到一个引导箱模式对话框中。我为此模板声明了以下事件处理程序:

Template.modalTest.events({
    'click #modalTestIncrement': function(e, t) {
        console.log('click');
        Session.set('modalTestNumber', Session.get('modalTestNumber') + 1);
    }
});

以下是我尝试过的所有事情,以及它们的结果:

bootbox.dialog({
    message: Template.modalTest()
});

这会呈现模板,它看起来或多或少像0 Increment (in a button). 但是,当我Session从控制台更改变量时,它不会更改,并且当我单击按钮时不会调用事件处理程序(console.log甚至不会发生)。

message: Meteor.render(Template.modalTest())

message: Meteor.render(function() { return Template.modalTest(); })

Template这些都与调用本身完全相同。

message: new Handlebars.SafeString(Template.modalTest())

这只是将模态体呈现为空。模态仍然会弹出。

message: Meteor.render(new Handlebars.SafeString(Template.modalTest()))

Template和纯Meteor.render调用完全一样;模板在那里,但它没有反应性或事件响应。

是不是我正在使用这种较少的引导程序包而不是标准包?

我怎样才能让它以适当的反应流星风格呈现?

侵入 Bootbox?

我只是尝试侵入bootbox.js文件本身,看看我是否可以接管。我改变了一些东西,以便在bootbox.dialog({})层我只需传递我想要渲染的模板的名称:

// in bootbox.js::exports.dialog
console.log(options.message); // I'm passing the template name now, so this yields 'modalTest'

body.find(".bootbox-body").html(Meteor.render(Template[options.message]));

body.find(".bootbox-body").html(Meteor.render(function() { return Template[options.message](); }));

这两个不同的版本(不要担心它们是两种不同的尝试,而不是同时)它们都以非反应性方式呈现模板,就像它们之前所做的那样。

入侵引导箱会有什么不同吗?

提前致谢!

4

5 回答 5

5

我正在使用当前 0.9.3.1 版本的 Meteor 给出答案。如果要渲染模板并保持反应性,则必须:

  • 在父节点中渲染模板
  • 让父级已经在 DOM 中

所以这个非常短的函数就是这样做的答案:

    renderTmp = function (template, data) {
        var node = document.createElement("div");
        document.body.appendChild(node);
        UI.renderWithData(template, data, node);
        return node;
    };

在你的情况下,你会这样做:

    bootbox.dialog({
        message: renderTmp(Template.modalTest)
    });
于 2014-10-10T22:34:22.733 回答
5

流星 1.0+ 的答案:

创建引导框对话框后,使用Blaze.renderBlaze.renderWithData将模板渲染到引导框对话框中。

    function openMyDialog(fs){ // this can be tied to an event handler in another template
      <! do some stuff here, like setting the data context !>
      bootbox.dialog({
        title: 'This will populate with content from the "myDialog" template',
        message: "<div id='dialogNode'></div>",
        buttons: {
          do: {
            label: "ok",
            className: "btn btn-primary",
            callback: function() {
              <! take some actions !>
            }
          }
        }
      });
      Blaze.render(Template.myDialog,$("#dialogNode")[0]);
    };

这假设您定义了一个模板:

    <template name="myDialog">
      Content for my dialog box
    </template>

Template.myDialog为您使用的每个模板创建。

$("#dialogNode")[0]选择您设置的 DOM 节点

    message: "<div id='dialogNode'></div>"

或者,您可以message留空并使用$(".bootbox-body")来选择父节点。

可以想象,这还允许您message动态更改引导框对话框的部分。

于 2014-12-12T03:45:01.310 回答
0

为了以编程方式呈现 Meteor 模板,同时保持它们的反应性,您需要使用Meteor.render(). 他们在模板下的文档中解决了这个问题。

因此,为了让您的处理程序等工作,您可以使用:

bootbox.dialog({
    message: Meteor.render(function() { return Template.modalTest(); })
});

这对我来说也是一个重大问题!

我看到你真的很接近Meteor.render()'s。让我知道它是否仍然不起作用。

于 2014-03-15T02:13:21.703 回答
0

这适用于 Meteor 1.1.0.2

假设我们有一个名为 changePassword 的模板,它有两个字段分别为 oldPassword 和 newPassword,下面是一些使用模板弹出对话框然后获取结果的代码。

bootbox.dialog({
    title: 'Change Password',
    message: '<span/>', // Message can't be empty, but we're going to replace the contents
    buttons: {
      success: {
        label: 'Change',
        className: 'btn-primary',
        callback: function(event) {
          var oldPassword = this.find('input[name=oldPassword]').val();
          var newPassword = this.find('input[name=newPassword]').val();
          console.log("Change password from " + oldPassword + " to " + newPassword);
          return false; // Close the dialog
        }
      },
      'Cancel': {
        className: 'btn-default'
      }
    }
  });
  // .bootbox-body is the parent of the span, so we can replace the contents
  // with our template
  // Using UI.renderWithData means we can pass data in to the template too.
  UI.insert(UI.renderWithData(Template.changePassword, {
    name: "Harry"
  }), $('.bootbox-body')[0]);
于 2015-05-09T13:01:45.277 回答
0

使用最新版本的 Meteor,这是一种将 doc 渲染到 bootbox 中的简单方法

let box = bootbox.dialog({title:'',message:''});
box.find('.bootbox-body').remove();
Blaze.renderWithData(template,MyCollection.findOne({_id}),box.find(".modal-body")[0]);

如果您希望对话框具有反应性,请使用

let box = bootbox.dialog({title:'',message:''});
box.find('.bootbox-body').remove();
Blaze.renderWithData(template,function() {return MyCollection.findOne({_id})},box.find(".modal-body")[0]);
于 2016-04-19T04:04:44.733 回答