Javascript 同一页面上的多个KnockoutJs组件分别运行
我是一个新手,在一个页面上有一个组件的多个实例 后台。组件从数据服务动态获取对象数组。根据用户的操作,组件可能需要重新渲染阵列(提供新对象),因此阵列是可观察的 问题。页面上必须有多个组件实例,但它们必须独立工作。即使最初它们接收相同的对象数组 我创建了一个简单的例子来说明这个问题 HTMLJavascript 同一页面上的多个KnockoutJs组件分别运行,javascript,knockout.js,Javascript,Knockout.js,我是一个新手,在一个页面上有一个组件的多个实例 后台。组件从数据服务动态获取对象数组。根据用户的操作,组件可能需要重新渲染阵列(提供新对象),因此阵列是可观察的 问题。页面上必须有多个组件实例,但它们必须独立工作。即使最初它们接收相同的对象数组 我创建了一个简单的例子来说明这个问题 HTML 模拟数据服务调用: 拉动 构成部分1: 构成部分2: JavaScript ko.components.register("item-picker", { viewModel: function(pa
模拟数据服务调用:
拉动
构成部分1:
构成部分2:
JavaScript
ko.components.register("item-picker", {
viewModel: function(params) {
var self = this;
self.items = params.items;
self.addPerson = function() {
self.items.push({
name: "New at " + new Date()
});
};
},
template: "<button data-bind='click: addPerson'>Add</button><div data-bind='foreach: items'><p data-bind='text: name'></p></div>"
});
// top level viewmodel
var vm = function() {
var self = this;
self.itemsArray = ko.observableArray([]);
self.getData = function(){
self.itemsArray([]);
self.itemsArray.push({name: 'Bert'}, {name: 'Charles'}, {name: 'Denise'});
};
};
ko.applyBindings(new vm());
ko.components.register(“项目选择器”{
viewModel:函数(参数){
var self=这个;
self.items=参数项;
self.addPerson=函数(){
self.items.push({
名称:“新日期”+新日期()
});
};
},
模板:“添加”
});
//顶层视图模型
var vm=函数(){
var self=这个;
self.itemsArray=ko.observearray([]);
self.getData=function(){
self.itemsArray([]);
self.itemsArray.push({name:'Bert'},{name:'Charles'},{name:'Denise'});
};
};
应用绑定(新vm());
该示例也可在JSFIDLE上获得:
编辑
我应该提到数据服务调用是异步的,数据可能会在页面加载之后接收,并且用户可以强制重新检索数据(例如使用不同的参数)。我已经相应地更新了JSFIDLE上的代码片段和示例
问题。在JSFIDLE示例中,如何使组件独立工作?
即,向“组件1”添加新名称不应向“组件2”添加名称在构造函数中创建新的可观察数组包装器和内部数组:
self.items = ko.observableArray(params.items().slice(0));
当前结构中有两层:
vm.itemsArray中的observearray
实例
observableArray
,请再次调用ko.observableArray
。为了创建原始列表的副本,(请注意,对象引用仍然相同!),我使用了slice
编辑:
上述方法将组件与原始阵列解耦。如果要保留关系但不修改源,可以执行以下操作:
在您的组件中:
self.myItems = ko.observableArray([]);
self.items = ko.pureComputed(function() {
return params.items().concat(self.myItems());
});
您按下
myItems
,这将触发计算结果的更新。对源可观测数组的任何更改也会触发更新。如果愿意,您甚至可以添加排序。在构造函数中创建新的可观察数组包装器和内部数组:
self.items = ko.observableArray(params.items().slice(0));
当前结构中有两层:
vm.itemsArray中的observearray
实例
observableArray
,请再次调用ko.observableArray
。为了创建原始列表的副本,(请注意,对象引用仍然相同!),我使用了slice
编辑:
上述方法将组件与原始阵列解耦。如果要保留关系但不修改源,可以执行以下操作:
在您的组件中:
self.myItems = ko.observableArray([]);
self.items = ko.pureComputed(function() {
return params.items().concat(self.myItems());
});
您按下
myItems
,这将触发计算结果的更新。对源可观测数组的任何更改也会触发更新。如果您愿意,您甚至可以添加排序。这听起来像是一个非常有前途的解决方案,我的缺点是数据服务调用是异步的,用户可以随时重新触发。我已经更新了我的问题。您知道如何在这种情况下制作数组包装器吗?创建一个名为myItems的可观察数组,addItem将其推送到。创建一个计算数组,该数组对myItems和parent.items()进行合并。使用foreach绑定中的最后一个计算数组。非常感谢,您救了我的周末!:)你的解决方法引导我解决了这个问题。最后一点我必须修复的是DTOs实例化,它现在可以工作了:)这听起来像是一个非常有前途的解决方案,我的缺点是数据服务调用是异步的,用户可以随时重新触发。我已经更新了我的问题。您知道如何在这种情况下制作数组包装器吗?创建一个名为myItems的可观察数组,addItem将其推送到。创建一个计算数组,该数组对myItems和parent.items()进行合并。使用foreach绑定中的最后一个计算数组。非常感谢,您救了我的周末!:)你的解决方法引导我解决了这个问题。我必须修复的最后一点是DTOs实例化,它现在可以工作了:)