将所选项目从多选列表复制到其他多选列表

时间:2014-02-13 10:27:38

标签: jquery knockout.js

我有2个多选列表,我希望能够将列表中的所选项目复制到另一个列表中。 我只想修改viewmodel上的属性,直到点击“保存”按钮并通过ajax调用或knockout post发布到控制器。

有什么方法可以实现这个目标吗?

感谢正手!

jsfiddle:

    'http://jsfiddle.net/aDahT/1420/

1 个答案:

答案 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/