如何在 ko.observableArray() 中使用自定义绑定 [英] How to use custom binding with ko.observableArray()

查看:25
本文介绍了如何在 ko.observableArray() 中使用自定义绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

敲除自定义绑定如何与 observableArray 一起工作?将 ko.observable() 与自定义绑定一起使用时,一切都按预期工作.使用 ko.observableArray() 时,只抛出初始事件(初始化和更新一次),但不会检测到进一步的更改(参见 Fiddle 或下面的代码).

<头><script type="text/javascript" src="knockout-2.2.1.js"><身体><div data-bind="text: Observable, updateBinding: Observable"></div><div data-bind="foreach: ObservableArray, updateBinding: ObservableArray"><span data-bind="text: $data"></span>

<script type="text/javascript">ko.bindingHandlers['updateBinding'] = {初始化:函数(元素,valueAccessor,allBindingsAccessor,viewModel,bindingContext){alert("绑定处理程序(初始化)");},更新:函数(元素,valueAccessor,allBindingsAccessor,viewModel,bindingContext){alert("绑定处理程序(更新)");}};函数视图模型(){var self = this;self.ObservableArray = ko.observableArray();self.Observable = ko.observable();}var viewModel = new ViewModel();//为 Observable 和 ObservableArray 触发初始化 + 更新ko.applyBindings(viewModel);//为 Observable 触发更新viewModel.Observable(1);//什么也没做viewModel.ObservableArray.push('1');

解决方案

您需要在自定义绑定中创建对 observableArray 的依赖.所以,至少是这样的:

 ko.bindingHandlers.updateBinding = {初始化:函数(元素,valueAccessor,allBindingsAccessor,viewModel,bindingContext){alert("绑定处理程序(初始化)");},更新:函数(元素,valueAccessor,allBindingsAccessor,viewModel,bindingContext){//创建一个依赖,通常你会用'data'做一些事情var data = ko.utils.unwrapObservable(valueAccessor());alert("绑定处理程序(更新)");}};

这适用于您的可观察示例的原因是因为单个元素上的所有绑定都是一起触发的(更多信息 此处).

这在其他绑定上的行为方式不同的原因是 foreach 的行为方式不同.对 observableArray 的更改不会直接触发 foreach 绑定(或者整个部分将被重新渲染).相反,它在单独的 ko.computed 中触发逻辑,该逻辑评估数组如何更改并进行必要的增量更新(添加项目、删除项目等).

How does knockout custom binding work with observableArray? When using ko.observable() with custom binding, everything works as expected. When using ko.observableArray(), only the initial events (init and update once) are thrown, but further changes are not detected (see Fiddle or code below).

<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript" src="knockout-2.2.1.js"> </script>
</head>
<body>
    <div data-bind="text: Observable, updateBinding: Observable"></div>
    <div data-bind="foreach: ObservableArray, updateBinding: ObservableArray">
        <span data-bind="text: $data"></span>
    </div>
    <script type="text/javascript"> 
        ko.bindingHandlers['updateBinding'] = {
            init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
                alert("Binding Handler (Init)");
            },
            update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
                alert("Binding Handler (Update)");
            }
        };

        function ViewModel() {
            var self = this;

            self.ObservableArray = ko.observableArray();
            self.Observable = ko.observable();
        }

        var viewModel = new ViewModel();

        // Fires Init + Update for Observable and ObservableArray
        ko.applyBindings(viewModel);

        // Fires Update for Observable
        viewModel.Observable(1);

        // Does nothing
        viewModel.ObservableArray.push('1');
    </script>
</body>
</html>

解决方案

You will want to create a dependency on your observableArray within your custom binding. So, at the very least something like:

    ko.bindingHandlers.updateBinding = {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
            alert("Binding Handler (Init)");
        },
        update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
            //create a dependency, normally you would do something with 'data'
            var data = ko.utils.unwrapObservable(valueAccessor());
            alert("Binding Handler (Update)");
        }
    };

The reason that this works with your observable example is because all bindings on a single element are triggered together (more info here).

The reason that this does not behave the same way on your other binding is that foreach behaves differently. Changes to the observableArray do not trigger the foreach binding directly (or the whole section would be re-rendered). Instead it triggers logic in a separate ko.computed that evaluates how the array has changed and makes the necessary incremental updates (add an item, remove an item, etc.).

这篇关于如何在 ko.observableArray() 中使用自定义绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆