knockoutjs在项目选中时创建新对象

时间:2016-06-02 11:50:54

标签: knockout.js

按照淘汰文档中的这个例子:

<!-- ko foreach: items -->
    <input type="checkbox" data-bind="checkedValue: $data, checked: $root.chosenItems" />
    <span data-bind="text: itemName"></span>
<!-- /ko -->

<script type="text/javascript">
    var viewModel = {
        items: ko.observableArray([
            { itemName: 'Choice 1' },
            { itemName: 'Choice 2' }
        ]),
        chosenItems: ko.observableArray()
    };
</script>

我创建了一个对象列表,当使用复选框进行检查时,会添加到新列表(selectedItems)。

我想要做的是让我选择的项目列表包含具有一些额外属性的对象。例如,如果我从上面选择“选择1”,我希望我选择的项目看起来像:

[ { itemName: 'Choice 1', itemTitle : "", somethingElse : "" }]);

我设法通过创建另一个observableArray并订阅selectedItems来做到这一点,然后当selectedItems改变时,我手动重新创建第二个数组,但我想知道是否有更简洁的方式?

2 个答案:

答案 0 :(得分:0)

var viewModel = {
    items: ko.observableArray([
        { itemName: 'Choice 1' },
        { itemName: 'Choice 2' }
    ]),
    chosenItems: ko.observableArray(),

};
viewModel.chosenItems.subscribe(function(chkVals){                  
    if(chkVals && chkVals.length > 0){
        var obj = chkVals[chkVals.length-1];
        if(!obj.itemTitle || !obj.itemTitle)
        {                   
            obj.itemTitle ='abc'+chkVals.length;
            obj.somethingElse  ='def'+chkVals.length;
        }
    }
    }); 

答案 1 :(得分:0)

您可以将整个复杂对象放入所选项目列表中。缺点是预先填充选定值列表会变得有点棘手。一个jquery grep在这里派上用场。

https://jsfiddle.net/4p3bsgmg/1/

    <!-- ko foreach: items -->
        <input type="checkbox" data-bind="checkedValue: $data, checked: $root.chosenItems" />
        <span data-bind="text: displayName"></span>
    <!-- /ko -->
    <br/><br/>
    Chosen Items: <span data-bind='text: ko.toJSON(chosenItems)'></span>



<script>
    var viewModel = {
        items: ko.observableArray([
            { id : 1, displayName: "Bob's Burgers", name : "Robert J. Burger Co." },
            { id : 2, displayName: "Late Nite Slice", name : "Pizza Inc." },
            { id : 3, displayName: "Luigie's Pizza Tower", name : "Pizza Inc." }
        ]),
        chosenItems: ko.observableArray(),
        load: function(selectedItems){
            var selectedItems = $.grep(this.items(), function(val){
                return selectedIdsFromAWebmethodCall.indexOf(val.id) >= 0;
            });
            for(var i = 0; i < selectedItems.length; i++){
                this.chosenItems.push(selectedItems[i]);
            }
        }
    };

    ko.applyBindings(viewModel);
    var selectedIdsFromAWebmethodCall = [1];
    viewModel.load(selectedIdsFromAWebmethodCall);
</script>