我有2个多选列表,我希望能够将列表中的所选项目复制到另一个列表中。 我只想修改viewmodel上的属性,直到点击“保存”按钮并通过ajax调用或knockout post发布到控制器。
有什么方法可以实现这个目标吗?
感谢正手!
jsfiddle:
'http://jsfiddle.net/aDahT/1420/
答案 0 :(得分:1)
首先,您需要在viewmodel中将变量设置为'this'的值,以便能够访问其他可观察数组:
var SProcsViewModel = function () {
var self=this;
否则在“复制到DB2”按钮上,这个值将是Window,而不是您的viewmodel。
然后,从一个可观察数组复制到另一个可观察数组:
ko.utils.arrayForEach(self.selectedStoredProceduresInDb1(), function(value){
console.log(value,this,self.storedProceduresInDB2);
sprocs.push(value);
});
knockout utils的arrayForEach,干净地遍历可观察数组,value将是数组项,而不是数组的索引(如$ .each)。
(非常值得深入研究文档中的ko.utils:ko utils docs
您可以使用$ .each执行循环:
$.each(self.selectedStoredProceduresInDb1(), function(value){
console.log(value,self.selectedStoredProceduresInDb1()[value]);
sprocs.push(self.selectedStoredProceduresInDb1()[value]);
});
注意它有点复杂,因为你必须先担心首先访问observable数组然后再访问该数组的索引。
当您将列表中的所选项目添加到新阵列sprocs
时,您尝试将它们推送到数组,但由于将有多个项目,您需要使用apply:
self.storedProceduresInDB2.push.apply(self.storedProceduresInDB2,sprocs);
这将合并2个数组。
然后您将在列表中包含所选项目,然后您可以在准备好时调用AJAX代码进行更新。
我创造了一个上述变化的小提琴。 http://jsfiddle.net/jiggle/7zp5K/
更新:仅在选项列表中添加项目(如果尚未添加):
ko.utils.arrayForEach(self.selectedStoredProceduresInDb1(), function(value){
console.log(value,self.storedProceduresInDB2);
var match = ko.utils.arrayFirst(self.storedProceduresInDB2(), function(item) {
return value === item;
});
if (!match){
sprocs.push(value);
}
});
这使用ko.utils arrayFirst,循环遍历列表中的所有项目,如果找到该项目,则返回true。
然后我们检查匹配是否未定义(未找到)与!匹配,如果是(它不在列表中),请将其添加到列表中
我已经更新了小提琴以包含此代码。
补充:在关于更改代码以使用JSON对象而不仅仅是ids ....的评论中回答Henrick问题:
从<select>
(两者都)中删除optionsValue:'Id'参数:
从:
<select multiple="multiple" height="5" data-bind="options:storedProceduresInDB1,
optionsText: 'Name', optionsValue: 'Id', selectedOptions:selectedStoredProceduresInDb1"> </select>
为:
<select multiple="multiple" height="5" data-bind="options:storedProceduresInDB1,
optionsText: 'Name', selectedOptions:selectedStoredProceduresInDb1"> </select>
这会将所选项目绑定到对象本身,而不是对象的Id属性。
然后在代码中,您必须在所选项目的Id属性(现在是完整对象)上查找匹配项
var match = ko.utils.arrayFirst(self.storedProceduresInDB2(), function(item) {
console.log('item in storedProceduresInDB2',value,item);
return value.Id === item.Id; //match to the Id property of the selected object
});
看到新的工作小提琴:http://jsfiddle.net/jiggle/7zp5K/