简体   繁体   English

淘汰赛JS无法从observableArray中删除对象

[英]Knockout js unable to remove object from observableArray

I've got two ways that I'm filling in an observableArray, one for testing purposes and one for the way I intend on using this array. 我有两种填写ObservableArray的方法,一种用于测试目的,一种用于我打算使用此数组的方式。

The first way I'm defining these objects and pushing them in one at a time, the second way I'm reading a JSON stream and pushing them in with a loop. 第一种方法是定义这些对象,然后一次将其推入其中;第二种方法是,读取JSON流并通过循环将其推入其中。

Here's my code for this shuttle-menu I'm using. 这是我正在使用的快速菜单的代码。

var StateModel = function() {
    var self = this;
    // initialize containers
    self.leftStateBox = ko.observableArray();
    self.rightStateBox = ko.observableArray();

    // selected ids
    self.selectedLeftStateBox = ko.observableArray();
    self.selectedRightStateBox = ko.observableArray();

    self.moveLeft = function () {
        var sel = self.selectedRightStateBox();
        for (var i = 0; i < sel.length; i++) {
            var selCat = sel[i];
            var result = self.rightStateBox.remove(function (item) {
                return item.id == selCat;
            });
            if (result && result.length > 0) {
                self.leftStateBox.push(result[0]);
            }
        }
        self.selectedRightStateBox.removeAll();
    }

    self.moveRight = function () {
        var sel = self.selectedLeftStateBox();
        for (var i = 0; i < sel.length; i++) {
            var selCat = sel[i];
            var result = self.leftStateBox.remove(function (item) {
                return item.id == selCat;
            });
            if (result && result.length > 0) {
                self.rightStateBox.push(result[0]);
            }
        }
        self.selectedLeftStateBox.removeAll();
    }


    self.leftStateBox.push({
        id: "CAA"
        , name: 'State 1'
    });
    self.leftStateBox.push({
        id: "VAA"
        , name: 'State 2'
    });
    self.leftStateBox.push({
        id: "BAA"
        , name: 'State 3'
    });

    self.loadStates = function() {
        var self = this;
        $.getJSON("${baseAppUrl}/public/company/" + companyId + "/json/searchStates/list",
            function (searchStatesData) {
                var states = JSON.parse(searchStatesData).searchStates;
                for(var i = 0; i < states.length; i++) {
                    self.leftStateBox.push(new State(states[i]));
                }
            });
    };
    self.loadStates();
}        

var State = function (state) {
    var self = this;
    self.name = ko.observable(state.name);
    self.id = ko.observable(state.id);
}

$(function () {
    ko.applyBindings(new StateModel(), document.getElementById("statesBox"));
});

Here's my view section: 这是我的观点部分:

'<div id="statesBox">
    <div>
        Available States:
        <select multiple='multiple' data-bind="options: leftStateBox, optionsText: 'name', optionsValue: 'id', selectedOptions: selectedLeftStateBox"></select>
    </div>
    <div>
        <p><button data-bind="click: moveRight">Add Selected</button></p>
        <p><button data-bind="click: moveLeft">Remove Selected</button></p>
    </div>
    <div>
        Selected States:
        <select multiple='multiple' data-bind="options: rightStateBox, optionsText: 'name', optionsValue: 'id', selectedOptions: selectedRightStateBox"></select>
    </div>
    <br /><br />
</div>'

When I try to shuttle things back and forth on the list it works for the three I manually entered in but it doesn't work for the ones imported through the JSON call. 当我尝试在列表上来回穿梭时,它适用于我手动输入的三个条目,但不适用于通过JSON调用导入的条目。 They all show up on the list though and seem to have the same information, I structured the manually created objects after how the JSON objects look. 它们全部都显示在列表中,并且似乎具有相同的信息,我根据JSON对象的外观构造了手动创建的对象。 When I trace the JS function moveRight, the remove works for the manually created objects but fails on the imported ones. 当我跟踪JS函数moveRight时,remove适用于手动创建的对象,但对导入的对象却失败。 I'm not really sure what I'm doing wrong at this point, has anyone seen something like this? 我现在不确定自己在做什么错,有人看到过类似的东西吗?

I grabbed the shuttle menu code from this post 我从这篇文章中获取了穿梭菜单代码

The items you're adding have an important difference. 您要添加的项目具有重要区别。

self.leftStateBox.push({
    id: "BAA"
    , name: 'State 3'
});

...

var State = function (state) {
    var self = this;
    self.name = ko.observable(state.name);
    self.id = ko.observable(state.id);
}

The first have non-observable property values and the second have observable property values. 第一个具有不可观察的属性值,第二个具有可观察的属性值。 In general, you should only make things observable if they need to be so (are you ever going to want to change the name or id of an item?). 通常,只有在需要时,才应使它们可见(您是否要更改项目的名称或ID?)。

var State = function (state) {
    var self = this;
    self.name = state.name;
    self.id = state.id;
}

If a property is always observable, you can just "unwrap" it directly: item.id() . 如果某个属性始终是可观察的,则可以直接将其“展开”: item.id() If it may sometimes be observable, you can use ko.unwrap(item.id) . 如果有时可以观察到,则可以使用ko.unwrap(item.id)

var result = self.rightStateBox.remove(function (item) {
    return ko.unwrap(item.id) == selCat;
});

Manipulating arrays is very easy by using underscore js 使用下划线js操作数组非常容易

you can easily remove an item in KO observable array by the following code. 您可以通过以下代码轻松删除KO可观察数组中的项目。

 self.rightStateBox(_.without(self.rightStateBox(), toRemove));

toRemove is the object to remove from the array. toRemove是要从数组中删除的对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM