KnockoutJs - 为什么 init 绑定处理程序只被调用一次?

发布于 2024-12-12 04:39:37 字数 1468 浏览 2 评论 0原文

我有一个问题,即第二次从服务器更新数据时没有调用 init: 函数。

有什么原因可能会发生这种情况吗?

我正在使用映射插件。我不明白的另一个问题是我是否需要根据这是第一次调用还是第二次调用以不同的方式调用映射插件函数?

JS

 function ViewMemberPopup(memberId) {

        $.get("/People/GetMemberDetails?memberId=" + memberId, function (data) {            
            viewMemberModel.model = ko.mapping.fromJS(data);            
            ko.applyBindings(viewMemberModel.model, $("#memberDetailsContainer")[0]);
        });
    }


 // binding handler
 ko.bindingHandlers.renderMemberModal = {
        init: function (element, valueAccessor, allBindingsAccessor) {
            $(element).modal("show");            
        }
    };

HTML: 我已经使用 renderMemberModal:true 作为绑定处理程序,不知道为什么我需要附加一个属性。我只需要调用渲染函数...

     <div class="modal fade" id="viewMemberModal" data-bind="renderMemberModal: true" style="display: none;">
        <div class="modal-header">
            <a class="close" href="#">×</a>
            <h3>
                Member Details</h3>
        </div>
        <div class="modal-body">
             <div data-bind="template: { name: 'memberDetailsTemplate' }">
            </div>
        </div>
        <div class="modal-footer">
            <a class="btnx closeModal">Close</a>
        </div>
    </div>

我正在使用 bootstrap css 来显示模式弹出窗口。

I have a problem whereby the init: function is not being called on the 2nd time the data is updated from the server.

Is there any reason why this might happen?

I'm using the mapping plugin. Another issue I don't understand is do I need to call the mapping plugin function differently depending on whether this is the 1st call or 2nd call?

JS

 function ViewMemberPopup(memberId) {

        $.get("/People/GetMemberDetails?memberId=" + memberId, function (data) {            
            viewMemberModel.model = ko.mapping.fromJS(data);            
            ko.applyBindings(viewMemberModel.model, $("#memberDetailsContainer")[0]);
        });
    }


 // binding handler
 ko.bindingHandlers.renderMemberModal = {
        init: function (element, valueAccessor, allBindingsAccessor) {
            $(element).modal("show");            
        }
    };

HTML:
I've used renderMemberModal:true for the binding handler, not sure why I need a property attached to it. I just need to call the render function...

     <div class="modal fade" id="viewMemberModal" data-bind="renderMemberModal: true" style="display: none;">
        <div class="modal-header">
            <a class="close" href="#">×</a>
            <h3>
                Member Details</h3>
        </div>
        <div class="modal-body">
             <div data-bind="template: { name: 'memberDetailsTemplate' }">
            </div>
        </div>
        <div class="modal-footer">
            <a class="btnx closeModal">Close</a>
        </div>
    </div>

I'm using bootstrap css to show the modal pop-up.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

栖竹 2024-12-19 04:39:37

您通常不希望在每次更新时继续对同一元素调用 applyBindings。这最终可能会添加多个事件处理程序,具体取决于您使用的绑定。如果您要这样做,那么您至少需要在该元素上调用 ko.cleanNode 。类似于: http://jsfiddle.net/rniemeyer/F4AzB/

而不是在每次更新时调用 applyBindings ,我认为让 template 绑定(或作为模板绑定包装器的控制流绑定)处理内容更新会更容易。

您的 viewModel 可以有一个 observable 来表示您的数据。然后,您可以使用数据的新副本更新该可观察值。

在这种情况下,您真正​​想要做的是让您的自定义绑定只有一个更新函数,并确保访问主要的可观察对象,以便每次调用更新函数时它都会触发。

ko.bindingHandlers.custom = {
    update: function(element, valueAccessor) {
        ko.utils.unwrapObservable(valueAccessor());  //just for subscription
        console.log("hit");
    }  
};

看起来像这样: http://jsfiddle.net/rniemeyer/dNsW8/

You would usually not want to keep calling applyBindings on the same element on each update. This can end up adding multiple event handlers depending on the bindings that you use. If you were to do that, then you would want to at least call ko.cleanNode on the element. Something like: http://jsfiddle.net/rniemeyer/F4AzB/

Rather than call applyBindings on each update, I think that it is easier to let the template binding (or control-flow bindings that are wrappers to the template binding) handle updating the content.

Your viewModel could have an observable to represent your data. Then, you could update that observable with new copies of your data.

In that case, what you would really want to do is have your custom binding just have an update function and be sure to access the main observable, so that it fires every time you call your update function.

ko.bindingHandlers.custom = {
    update: function(element, valueAccessor) {
        ko.utils.unwrapObservable(valueAccessor());  //just for subscription
        console.log("hit");
    }  
};

Would look something like this: http://jsfiddle.net/rniemeyer/dNsW8/

一瞬间的火花 2024-12-19 04:39:37

在 Knockoutjs 网站上 http://knockoutjs.com/documentation/custom-bindings.html讨论自定义绑定。

Knockout 将为您使用绑定的每个 DOM 元素调用一次 init 函数。 init 有两个主要用途:
- 为 DOM 元素设置任何初始状态
- 注册任何事件处理程序,以便例如当用户单击或修改 DOM 元素时,您可以更改关联的可观察对象的状态

因此,根据设计,仅调用 Init 一次来设置绑定。其目的是配置 DOM 对象,以便 Update 方法正确工作。

On the Knockoutjs site http://knockoutjs.com/documentation/custom-bindings.html discusses custom bindings.

Knockout will call your init function once for each DOM element that you use the binding on. There are two main uses for init:
- To set any initial state for the DOM element
- To register any event handlers so that, for example, when the user clicks on or modifies the DOM element, you can change the state of the associated observable

So by design, the Init is only called once to setup the binding. It's purpose to configure the DOM object so that the Update method works correct.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文