通知普通数组中的值已更改

时间:2015-06-11 13:22:04

标签: javascript knockout.js

目前我已经绑定了普通数组。可以通过外部组件更改阵列的值。

是否有可能发送值已更改的通知并重新呈现DOM树?

我无法使用observable,因此valueHasMutated不是解决方案,数组非常大并且包含许多复杂对象。

3 个答案:

答案 0 :(得分:1)

如果您可以将另一个对象(而不是原始数组)传递给使用者,那么您可以使用defineProperty来包装突变。

var original = new Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 0);
var wrapper = {};
for (var idx in original) {
    (function(prop) {
        Object.defineProperty(wrapper, prop, { 
            get: function() { return original[prop]; }, 
            set: function(v) { 
                console.log("changing index " + prop + " to " + v);
                original[prop] = v;
            }
        });
    })(idx);
}

显然,这仅在您更改索引处的值时才有效。如果您的数组包含对象并且您直接更改其中一个对象,例如original[0].property = "value",那么您需要扩展此技术以访问数组中的每个对象并创建包装对象的等效结构。

答案 1 :(得分:1)

我假设您使用Knockout.js,因为您标记了它。因此,您可以使用ko.ObservableArray()并将其绑定到DOM。

var originalArray = [1, 2, 3, 4];
var observableArray = ko.ObservableArray(originalArray);

请参阅this link

答案 2 :(得分:1)

如果我理解正确,该数组是ViewModel(您可以控制)的成员,但是您无法将其更改为observableArray,因为您控件之外的内容使用普通数组语法修改数组。此外,可以在这些黑盒函数运行后执行某些操作,以通知模型阵列可能已经发生变异。

我们可以做到这一点。定义一个(内部)observableArray并在包装它的ViewModel上定义一个公共属性。这使您可以使用普通数组语法访问observableArray。但是,对阵列中各个(非observable)元素的更改不会发送通知,因此您需要调用内部valueHasMutated的{​​{1}}方法,每当你做出改变时都会打电话。

observableArray

我们的应用可以像常规数组一样使用var vm = (function () { var arrayImpl = ['hi']; var obsArray = ko.observableArray(arrayImpl); var itemNumbers = [1,2,3,4,5,6,7,8,9]; var self = { itemNumbers: itemNumbers, selectedItemNumber: ko.observable(1), newValue: ko.observable(), arrayHasMutated:obsArray.valueHasMutated }; Object.defineProperty(self, 'plainArray', { get: obsArray, set: obsArray }); return self; }); ko.applyBindings(vm); 属性。进行更新后,请致电plainArray

arrayHasMutated

尝试一下:http://jsfiddle.net/4jogh3k5/1/