【问题标题】:Bootstrap popover template loses knockout bindingsBootstrap 弹出框模板丢失了淘汰赛绑定
【发布时间】:2016-07-03 22:40:26
【问题描述】:

我正在尝试制作一个弹出框,它有一个 html 表单和一个类型为“提交”的按钮。这个弹出框也绑定到了 knockout.js。

当我点击弹出框上的按钮时,它不会触发 KO 功能,而是发出标准的 post 请求。

如果我将表单移到弹出框之外,它可以正常工作。

如何在弹出窗口中创建 html 表单并使用提交按钮触发我的模型的功能?

这是non-working fiddle

<a href="#" id="createTaskPopover" data-toggle="popover" data-placement="right" title="Create Task">Click me!!!</a>

<div id="createTaskPopoverContent" class="hide">
    <form data-bind="submit: AddTask">
        <input type="hidden" id="FeatureId" name="FeatureId" value="" />
        <span>Name</span>
        <input type="text" id="Name" name="Name" style="width:100%;" /><br />

        <br />
        <button id="btnCreateNewTask" type="submit" class="btn btn-info">Create</button>
        <br />
    </form>
</div>
$('#createTaskPopover').popover({
        container: 'body',
        html: 'true',
        content: function () {
            return $("#createTaskPopoverContent").html();
        }
    });

function VM() {
    var self = this;
    self.AddTask = function (formElement) {
        console.log(formElement);
    }
}
var projectVM = new VM();
ko.applyBindings(projectVM);

【问题讨论】:

  • 您可能有兴趣查看 knockstrap,它有助于弥合 Bootstrap 和 Knockout 之间的差距。它有一个 specific binding 用于弹出框。
  • 我想,应该有办法,不用任何扩展。这不是我遇到的罕见问题。
  • 哦,是的 - 这当然不是你问题的答案,但知道这些东西有时存在会很方便 :) 看看你的具体问题,我认为这是因为你正在动态返回使用.html() 弹出窗口,因此此时它失去了submit 绑定。虽然我还没有解决方法......

标签: twitter-bootstrap knockout.js popover


【解决方案1】:

未触发该函数的原因是弹出框使用的 HTML 是在运行时注入的,并且已经应用​​了 Knockout 绑定:

content: function () {
           return $("#createTaskPopoverContent").html();
         }

选项 A:弹出框显示后执行 Knockout 绑定

$('#createTaskPopover').on('shown.bs.popover', function () {
  var projectVM = new VM();
  ko.applyBindings(projectVM);
})

选项 B:内联 HTML 并简化为 $('#createTaskPopover').popover()

data-content="raw HTML here" data-html="true"

【讨论】:

  • 选项 A 可能无法在更大规模的基于淘汰赛的网站上工作 - 我怀疑 OP 在此弹出框之外还会有其他由淘汰赛驱动的事情。选项 B 甚至会做任何淘汰赛数据绑定吗?我怀疑它会出现与当前代码完全相同的问题。
  • 选项A很难应用,原因正如詹姆斯所说。对于选项 B;它使代码难以阅读,维护将是一个问题。在实际场景中,我的原始 HTML 并不像这个例子那样简单。
  • 是的,这只是为了说明这一点,也可以将虚拟机和绑定分开。澄清了第二个选项。
【解决方案2】:

它不起作用的原因是因为您正在使用 .html() 调用复制 html,此时敲除绑定丢失了。实际上,您可以给 bootstrap 直接使用的元素,并结合显示的事件来删除 hide 类,它可以按照您的意愿工作:

$('#createTaskPopover').popover({
    container: 'body',
    html: 'true',
    content: $("#createTaskPopoverContent") //return element directly
}).on('shown.bs.popover', function() {
    $('#createTaskPopoverContent').removeClass('hide'); //remove hide when popover shown
});

Here's an updated fiddle。但请注意,当弹出窗口打开时,您会看到轻微的闪烁,同时它会“取消隐藏”内容。

这可以通过只传递内部的form(或者如果你愿意,你可以将它包装在另一个div)到弹出窗口来进一步改进,然后你甚至不需要处理显示的事件,并且一旦弹出框显示,您就不会看到“出现”的内容:

$('#createTaskPopover').popover({
    container: 'body',
    html: 'true',
    content: $("#createTaskPopoverContent > form") //select the form directly
});

Further updated fiddle.

【讨论】:

  • 这就是我的问题的答案。谢谢你的帮助。 +1 也是为了您的进一步改进。非常感谢。
  • @JustAnotherCodeLover 没问题!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-05
  • 2016-11-15
  • 1970-01-01
  • 2014-01-17
  • 1970-01-01
  • 2013-02-04
  • 1970-01-01
相关资源
最近更新 更多