简体   繁体   English

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

[英]Binding a custom handler twice in knockoutjs

I've written a custom binding handler to show a bootstrap popover in knockout:我编写了一个自定义绑定处理程序来在淘汰赛中显示引导弹出窗口:

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');
    }
};

...which works perfectly. ...它完美地工作。

However, when I try to bind it twice on the same element like this:但是,当我尝试在同一个元素上将它绑定两次时,如下所示:

<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' }" />

...it only binds the second one. ...它只绑定第二个。 I'm guessing this is because it's overwriting the first one.我猜这是因为它覆盖了第一个。

Is there a way to bind the same thing twice?有没有办法将同一个东西绑定两次?

There is one basic problem, which is that you can only show one popover at a time.有一个基本问题,即一次只能显示一个弹出窗口。 You could use some technique to support more than one popover in a single element , but that's not standard.您可以使用某种技术在单个元素中支持多个弹出框,但这不是标准的。

If you take into account this limitation of only being able to see one popover at a time, you can use a custom binding handler like this:如果您考虑到一次只能看到一个弹出窗口的限制,您可以使用这样的自定义绑定处理程序:

 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>

In this sample implementation you can specify several different popover configurations, but the visible one will be the first whose visible observable is true.在这个示例实现中,您可以指定几种不同的弹出框配置,但可见的将是第一个可见 observable 为 true 的。 You could modify this script in serveal ways:您可以通过多种方式修改此脚本:

  • include several divs in the same popover and control their visibility with the different visible observables.在同一个 popover 中包含多个 div,并使用不同的可见 observable 控制它们的可见性。 This should be done in the init , and the code in the update should stop destroying and recreating the popover这应该在init完成,并且update的代码应该停止销毁和重新创建弹出框
  • use some of the available techniques to show more than one popover in the same element使用一些可用的技术在同一元素中显示多个弹出框
  • forget about this implementation, and use invisible elements with your original popvoer in each of them忘记这个实现,并在每个元素中使用带有原始 popvoer 的不可见元素

If you pass some "popoverId" as binding parameter, you can store certain popup in the data:如果您传递一些“popoverId”作为绑定参数,您可以在数据中存储某些弹出窗口:

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

in init and get the popover in update:在 init 中并在更新中获取弹出框:

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

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

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