KnockoutJS:将一个 observble 数组作为参数传递给另一个会绑定它们吗?
KnockoutJS: Does passing one observble array as a parameter to another bind them?
我的应用程序中有两个可观察数组,我将一个作为参数传递给另一个,
model.arrayone(model.arrayTwo);
我注意到我在 arrayOne 中输入的内容会自动进入 arrayTwo,这是否意味着它们被绑定在一起
如果 model.arrayTwo
是 ko.observableArray 并且 model.arrayone
是 ko.observableArray 那么做 model.arrayone(model.arrayTwo);
将分配 model.arrayTwo
作为对你的可观察 model.arrayone
。这并不意味着它们是绑定的,这意味着它们引用了内存中的同一个地方..
发生的事情是两个可观察数组都绑定到同一个底层数组。可观察数组基本上是标准 javascript 数组的包装器,因此当您使用另一个可观察数组初始化一个可观察数组时,它们将成为相同数据的反映。
它们不是 "bound" 在剔除数据绑定意义上,但它们是绑定的,因为它们每个都引用了相同的源数据。
您所描述的行为
你的做法有点奇怪。这是一个复制品:
const arr1 = ko.observableArray([1]);
const arr2 = ko.observableArray([2]);
arr2(arr1);
arr2.push(2);
console.log(arr1()); // [ 1, 2 ]
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
为什么有效
由于 push
的 ko.observableArray
实施,此行为有效。此方法的工作方式是,它 窥视 可观察数组的内部值并对该对象调用 push
方法。来自消息来源:
ko.utils.arrayForEach(["pop", "push", "reverse", "shift", "sort", "splice", "unshift"],
function (methodName) {
ko.observableArray['fn'][methodName] = function () {
// Use "peek" to avoid creating a subscription in any computed that we're executing in the context of
// (for consistency with mutating regular observables)
var underlyingArray = this.peek();
this.valueWillMutate();
this.cacheDiffForKnownOperation(underlyingArray, methodName, arguments);
var methodCallResult = underlyingArray[methodName].apply(underlyingArray, arguments);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
this.valueHasMutated();
// The native sort and reverse methods return a reference to the array, but it makes more sense to return the observable array
// instead.
return methodCallResult === underlyingArray ? this : methodCallResult;
};
});
现在,您可以想象,这将导致 链 的 push
方法被转发,直到不再有可观察的数组。即:
- 致电
arr2.push
observableArray arr2
执行 .peek()
并找到对 observbaleArray arr1
的引用
- 致电
arr1.push
observableArray arr1
执行 .peek()
并找到对 常规 数组 [1]
的引用
Array.prototype.push
在 [ 1 ]
上添加 2
最终成为 [ 1, 2 ]
然后:
- 评价
arr1
returns[ 1, 2 ]
为什么这样嵌套 observableArray
是错误的:
当使用 null
、undefined
或数组实例以外的任何对象构造可观察数组时,您会收到以下方便的错误消息:
try {
ko.observableArray(ko.observableArray([]));
} catch(err) {
console.log(err.message);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
当设置一个可观察数组时,不再执行此检查(可能是因为性能?)。该规则仍然适用:
- 仅使用
observableArray
s 来保存数组
- 使用常规
observable
s 做其他事情
我的应用程序中有两个可观察数组,我将一个作为参数传递给另一个,
model.arrayone(model.arrayTwo);
我注意到我在 arrayOne 中输入的内容会自动进入 arrayTwo,这是否意味着它们被绑定在一起
如果 model.arrayTwo
是 ko.observableArray 并且 model.arrayone
是 ko.observableArray 那么做 model.arrayone(model.arrayTwo);
将分配 model.arrayTwo
作为对你的可观察 model.arrayone
。这并不意味着它们是绑定的,这意味着它们引用了内存中的同一个地方..
发生的事情是两个可观察数组都绑定到同一个底层数组。可观察数组基本上是标准 javascript 数组的包装器,因此当您使用另一个可观察数组初始化一个可观察数组时,它们将成为相同数据的反映。
它们不是 "bound" 在剔除数据绑定意义上,但它们是绑定的,因为它们每个都引用了相同的源数据。
您所描述的行为
你的做法有点奇怪。这是一个复制品:
const arr1 = ko.observableArray([1]);
const arr2 = ko.observableArray([2]);
arr2(arr1);
arr2.push(2);
console.log(arr1()); // [ 1, 2 ]
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
为什么有效
由于 push
的 ko.observableArray
实施,此行为有效。此方法的工作方式是,它 窥视 可观察数组的内部值并对该对象调用 push
方法。来自消息来源:
ko.utils.arrayForEach(["pop", "push", "reverse", "shift", "sort", "splice", "unshift"], function (methodName) { ko.observableArray['fn'][methodName] = function () { // Use "peek" to avoid creating a subscription in any computed that we're executing in the context of // (for consistency with mutating regular observables) var underlyingArray = this.peek(); this.valueWillMutate(); this.cacheDiffForKnownOperation(underlyingArray, methodName, arguments); var methodCallResult = underlyingArray[methodName].apply(underlyingArray, arguments); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this.valueHasMutated(); // The native sort and reverse methods return a reference to the array, but it makes more sense to return the observable array // instead. return methodCallResult === underlyingArray ? this : methodCallResult; }; });
现在,您可以想象,这将导致 链 的 push
方法被转发,直到不再有可观察的数组。即:
- 致电
arr2.push
observableArray arr2
执行.peek()
并找到对observbaleArray arr1
的引用
- 致电
arr1.push
observableArray arr1
执行.peek()
并找到对 常规 数组[1]
的引用
Array.prototype.push
在[ 1 ]
上添加2
最终成为[ 1, 2 ]
然后:
- 评价
arr1
returns[ 1, 2 ]
为什么这样嵌套 observableArray
是错误的:
当使用 null
、undefined
或数组实例以外的任何对象构造可观察数组时,您会收到以下方便的错误消息:
try {
ko.observableArray(ko.observableArray([]));
} catch(err) {
console.log(err.message);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
当设置一个可观察数组时,不再执行此检查(可能是因为性能?)。该规则仍然适用:
- 仅使用
observableArray
s 来保存数组 - 使用常规
observable
s 做其他事情