繁体   English   中英

在knockoutjs中两次绑定自定义处理程序

[英]Binding a custom handler twice in knockoutjs

我编写了一个自定义绑定处理程序来在淘汰赛中显示引导弹出窗口:

ko.bindingHandlers.popover = {
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {

        $(element).popover({
            html: true,
            content: function () { return $('#' + ko.unwrap(valueAccessor().template)).html(); },
            placement: "right",
            trigger: "manual",
            container: 'body'
        });

    },
    update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {

        if (valueAccessor().visible()) {
            $(element).popover('show');
            var popover = $("body .popover").last().get(0);
            ko.cleanNode(popover);
            ko.applyBindings(bindingContext.$rawData, popover);

        } else
            $(element).popover('hide');
    }
};

...它完美地工作。

但是,当我尝试在同一个元素上将它绑定两次时,如下所示:

<input type="password" class="form-control" id="login-password" placeholder="Password" data-bind="textInput: login.password.input, hasFocus: login.password.focus, popover: { visible: login.showBadPassword, placement: 'right', template: 'bad-password-popover' }, popover: { visible: login.showThrottled, placement: 'right', template: 'throttled-popover' }" />

...它只绑定第二个。 我猜这是因为它覆盖了第一个。

有没有办法将同一个东西绑定两次?

有一个基本问题,即一次只能显示一个弹出窗口。 您可以使用某种技术在单个元素中支持多个弹出框,但这不是标准的。

如果您考虑到一次只能看到一个弹出窗口的限制,您可以使用这样的自定义绑定处理程序:

 ko.bindingHandlers.popover = { init: function (element, valueAccessor, allBindings, viewModel, bindingContext) { }, update: function (element, valueAccessor, allBindings, viewModel, bindingContext) { var values = ko.unwrap(valueAccessor()); values.forEach(function(value) { value.visible(); }); debugger; var visibleValue = values.find(function(value) { return value.visible();}); if (visibleValue) { $(element).popover('destroy'); $(element).popover({ html: true, content: $('#' + ko.unwrap(visibleValue.template)).html(), placement: ko.unwrap(visibleValue.placement), container: 'body' }); $(element).popover('show'); var popover = $("body .popover").last().get(0); ko.cleanNode(popover); ko.applyBindings(bindingContext.$rawData, popover); } else { $(element).popover('hide'); }; } }; var vm = { triggerA: ko.observable(), triggerB: ko.observable() } ko.applyBindings(vm);
 <link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet"/> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <input type="password" data-bind="popover: [{visible: triggerA, placement: 'right', template: 'A'}, {visible: triggerB, placement: 'right', template: 'B'}]"/> <script type="text/html" id="A"> This is popover <b>A</b> </script> <script type="text/html" id="B"> This is popover <b>B</b> </script> <br/> <label>Trigger A<input type="checkbox" name="triggers" data-bind="checked: triggerA"></label> <label>Trigger B<input type="checkbox" name="triggers" data-bind="checked: triggerB"></label>

在这个示例实现中,您可以指定几种不同的弹出框配置,但可见的将是第一个可见 observable 为 true 的。 您可以通过多种方式修改此脚本:

  • 在同一个 popover 中包含多个 div,并使用不同的可见 observable 控制它们的可见性。 这应该在init完成,并且update的代码应该停止销毁和重新创建弹出框
  • 使用一些可用的技术在同一元素中显示多个弹出框
  • 忘记这个实现,并在每个元素中使用带有原始 popvoer 的不可见元素

如果您传递一些“popoverId”作为绑定参数,您可以在数据中存储某些弹出窗口:

var newPopover = $(element).popover({ /* some potions */ });
$(element).data(ko.unwrap(valueAccessor().popoverId, newPopover);

在 init 中并在更新中获取弹出框:

var popover = $(element).data(valueAccessor().popoverId);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM