Bootboxjs:如何将Meteor模板渲染为对话框主体

时间:2014-03-15 01:51:49

标签: meteor modal-dialog bootbox

我有以下模板:

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

session帮助只是与Session对象的中间人。我将modalTestNumber初始化为0

我希望将这个模板以及其所有的反应性渲染到bootbox模式对话框中。我为此模板声明了以下事件处理程序:

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甚至不会发生。)< / p>

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来电完全相同;模板在那里,但它没有反应性或事件响应。

我可能使用this less packaging of bootstrap而不是标准包吗?

如何以适当反应的流星风格渲染?

黑客入侵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](); }));

这两个不同的版本(不要担心它们是两次不同的尝试,而不是同时),它们都会像以前一样非反应性地渲染模板。

黑客入侵bootbox会有什么不同吗?

提前致谢!

5 个答案:

答案 0 :(得分:5)

我正在回答当前流行的0.9.3.1版本。 如果要渲染模板并保持反应性,则必须:

  • 在父节点中渲染模板
  • 让父母已经在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)
});

答案 1 :(得分:5)

回答Meteor 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部分。

答案 2 :(得分:0)

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

因此,对于您的处理程序等,您可以使用:

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

这对我来说也是一个主要问题!

我发现你与Meteor.render()的关系非常接近。如果它仍然不起作用,请告诉我。

答案 3 :(得分: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]);

答案 4 :(得分:0)

使用最新版本的Meteor,这是将文档呈现到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]);