如何在可观察数组中有条件地推送项目?

jaf*_*ffa 103 knockout.js

我想要push一个新项目observableArray,但只有当项目尚未存在时.在KnockoutJS中是否有任何"查找"功能或推荐的模式来实现这一目标?

我注意到a上的remove函数observableArray可以接收传递条件的函数.我几乎想要相同的功能,但是如果传入的条件是或者不是真的那么只推送它.

RP *_*yer 222

observableArray公开一个indexOf函数(包装器ko.utils.arrayIndexOf).这允许你这样做:

if (myObservableArray.indexOf(itemToAdd) < 0) {
  myObservableArray.push(itemToAdd);
}
Run Code Online (Sandbox Code Playgroud)

如果这两个实际上不是对同一对象的引用,并且您想要运行自定义比较逻辑,那么您可以使用ko.utils.arrayFirst如下:

var match = ko.utils.arrayFirst(myObservableArray(), function(item) {
    return itemToAdd.id === item.id;
});

if (!match) {
  myObservableArray.push(itemToAdd);
}
Run Code Online (Sandbox Code Playgroud)

  • 这将检查两者是完全相同的对象.如果需要检查单个属性,则可以使用`ko.utils.arrayFirst`.我将在答案中添加一个示例. (5认同)
  • 优秀的提示,但我不得不将itemToAdd.id === item.id更改为itemToAdd.id()=== item.id().我在下一个答案中发布了我的代码. (4认同)

Rak*_*e36 11

谢谢RP.这是一个使用您的建议通过对象的'id'属性从我的视图模型中返回'name'属性的示例.

    self.jobroles = ko.observableArray([]);

    self.jobroleName = function (id)
    {
        var match = ko.utils.arrayFirst(self.jobroles(), function (item)
        {
            return item.id() === id();  //note the ()
        });
        if (!match)
            return 'error';
        else
            return match.name;
    };
Run Code Online (Sandbox Code Playgroud)

在HTML中,我有以下内容($ parent是由于这是在一个表行循环中):

<select data-bind="visible: editing, hasfocus: editing, options: $parent.jobroles, optionsText: 'name', optionsValue: 'id', value: jobroleId, optionsCaption: '-- Select --'">
                            </select>
<span data-bind="visible: !editing(), text: $parent.jobroleName(jobroleId), click: edit"></span></td>
Run Code Online (Sandbox Code Playgroud)