Knockout.js 如何从可观察数组中删除淘汰验证validatedObservable

Knockout.js 如何从可观察数组中删除淘汰验证validatedObservable,knockout.js,knockout-validation,Knockout.js,Knockout Validation,我在视图模型的属性上有一个observableArray: self.rates=ko.observearray([]) 数组的内容显示在HTML表中。有一个按钮可将项目添加到数组中。这些是经过验证的可观测值: self.newRate = function () { var rate = new Rate({id: self.id}); rate.isEditing(true); rate.isNew = true; rate =

我在视图模型的属性上有一个observableArray:

self.rates=ko.observearray([])

数组的内容显示在HTML表中。有一个按钮可将项目添加到数组中。这些是经过验证的可观测值:

self.newRate = function () {
        var rate = new Rate({id: self.id});
        rate.isEditing(true);
        rate.isNew = true;
        rate = ko.validatedObservable(rate);
        self.vendor().rates.push(rate);
    };
这个很好用。该项将添加到阵列中,视图将更新。在新添加的项目旁边有一个cancel链接,允许用户删除该行

self.editRateCancel = function (item) {
    if (item.isNew === true) {
        self.vendor().rates.remove(item);
    } else {
        item.cancelEdit();
        ko.utils.arrayForEach(self.unitsOfMeasure(), function (uom) {
            if(item.cacheUnitOfMeasureID === uom.value) {
                item.selectedUOM(uom);
            }
        });
    }
};
调用
remove(item)
不会删除该项。如果我没有将该项设置为已验证的可观察项,则删除操作将成功。查看
remove
函数显示传入的项(valueOrPredicate)类型为
Object,(Rate)
,但从基础数组返回的值为
Object,(函数)
,因此
谓词(value)
返回false,因此该项不会被删除

KnockoutJS-remove函数:

ko.observableArray['fn'] = {
    'remove': function (valueOrPredicate) {
        var underlyingArray = this.peek();
        var removedValues = [];
        var predicate = typeof valueOrPredicate == "function" ? valueOrPredicate : function (value) { return value === valueOrPredicate; };
        for (var i = 0; i < underlyingArray.length; i++) {
            var value = underlyingArray[i];
            if (predicate(value)) {
                if (removedValues.length === 0) {
                    this.valueWillMutate();
                }
                removedValues.push(value);
                underlyingArray.splice(i, 1);
                i--;
            }
        }
        if (removedValues.length) {
            this.valueHasMutated();
        }
        return removedValues;
    },
ko.observearray['fn']={
“删除”:函数(值或预测){
var underyingarray=this.peek();
var removedValues=[];
var谓词=typeof valueOrPredicate==“函数”?valueOrPredicate:function(value){返回值===valueOrPredicate;};
对于(变量i=0;i

如何从可观察数组中删除特定的已验证可观察?是否有可用的实用函数?

我遇到了同样的问题,我尝试了以下方法:

第一种方法

创建一个可观察数组,使用
Rate
的实例和一个计算的可观察数组,该数组将从Rate返回每个项目作为
validatedObservable
。这种方法的问题是,每次向数组中添加或删除项目时,都会重新创建所有
validatedObservable
,这是无效的,并且会导致奇怪的错误我喜欢你的行为

第二种方法

Rate
创建一个额外的
deleted
可观察字段,并基于此字段的值创建一个
visible
绑定。这样,它将不会从可观察数组中删除,但对用户不可见

第三种方法

Rate
创建一个额外的
index
字段,并在父视图模型(包含
self.rates
)中保留一个
lastIndex
,初始值设置为0。然后,添加速率的函数如下所示:

self.newRate = function () {
    var rate = new Rate({id: self.id});
    rate.isEditing(true);
    rate.isNew = true;
    rate.index = lastIndex++;
    rate = ko.validatedObservable(rate);
    self.vendor().rates.push(rate);
};
self.editRateCancel = function (item) {
    if (item.isNew === true) {
        self.vendor().rates.remove(function (value) {
            // remember about parenthesis after value()
            // because it's an instance of validatedObservable()
            // and not an instance of Rate()
            return value().index == item.index;
        });
    } else {
        item.cancelEdit();
        ko.utils.arrayForEach(self.unitsOfMeasure(), function (uom) {
            if(item.cacheUnitOfMeasureID === uom.value) {
                item.selectedUOM(uom);
            }
        });
    }
};
移除该项的函数将使用谓词函数,如下所示:

self.newRate = function () {
    var rate = new Rate({id: self.id});
    rate.isEditing(true);
    rate.isNew = true;
    rate.index = lastIndex++;
    rate = ko.validatedObservable(rate);
    self.vendor().rates.push(rate);
};
self.editRateCancel = function (item) {
    if (item.isNew === true) {
        self.vendor().rates.remove(function (value) {
            // remember about parenthesis after value()
            // because it's an instance of validatedObservable()
            // and not an instance of Rate()
            return value().index == item.index;
        });
    } else {
        item.cancelEdit();
        ko.utils.arrayForEach(self.unitsOfMeasure(), function (uom) {
            if(item.cacheUnitOfMeasureID === uom.value) {
                item.selectedUOM(uom);
            }
        });
    }
};

我继续使用第三种方法,但第二种方法也可能为您所接受。

我刚刚遇到了这个问题,我的研究将我带到这里,因此我将记下我为解决这个问题所做的工作

knockout中的foreach绑定允许使用$index()访问当前元素的索引。我传递了索引,而不是使用将对象传递到remove函数的正常机制

例子

通常情况:

function ViewModel() {
    var self = this;
    .
    .
    .

    removeItem(item) {
        // Tries to remove matching object, fails on observables
        self.myArray.remove(item);
    }
}
function ViewModel() {
    var self = this;
    .
    .
    .

    removeItem(index) {
        // Removes 1 item at position of index 
        self.myArray.splice(index, 1);
    }
}
我的解决方法:

function ViewModel() {
    var self = this;
    .
    .
    .

    removeItem(item) {
        // Tries to remove matching object, fails on observables
        self.myArray.remove(item);
    }
}
function ViewModel() {
    var self = this;
    .
    .
    .

    removeItem(index) {
        // Removes 1 item at position of index 
        self.myArray.splice(index, 1);
    }
}
在解决方案中,html将如下所示

<div data-bind="foreach: myArray">
    <p data-bind="text: somePropertyOfTheObject"></p>
    // The bind call puts the index into the list of parameters of the function so it is available in the removeItems function
    <input type="button" value="remove" data-bind="click: $root.removeItem.bind(null, $index())" />
</div>

//bind调用将索引放入函数的参数列表中,以便它在removitems函数中可用
最后,我做了一把小提琴。

我没有意识到可以像您在第三种方法中描述的那样将函数传递给remove方法。这很好,因为它可以使代码保持简短。我最终基于KnockOutJS代码编写了自己的remove函数,但我认为我更喜欢您的代码。谢谢您的帮助。很高兴我能提供帮助:)我实际上也不知道我可以这样做直到我看到你发布的问题和代码,并想出了这个想法。所以也感谢你!