问题
I have a change occurring to an array. I am using Sanderson's latest array subscription method to catch the add/delete change. In this subscription is where I intend to bundle and send my request over the wire. If the request fails for any reason I want to be able to cancel any possible changes to the collection. I have verified that this subscription is hit before the change propagates so I assume there would be a way to say "STOP DON'T DO IT" however I can't figure out how.
As my example...
self.SourceData = ko.observableArray(data);
self.SourceData.subscribe(function(changes) {
var isAllGood = true;
ko.utils.arrayForEach(changes, function(ch) {
if (ch.value == doesNotMeetMyCondition) isAllGood = false;
});
if (!isAllGood) <STOP DON'T DO IT>
}, null, 'arrayChange');
When inspecting 'this' I do see the ko.subscription object with the standard [callback, dispose, disposeCallback, target] but nothing seems to amount to STOP DON'T DO IT.
Any thoughts would be quite helpful. Thanks.
回答1:
There is not currently a way to stop the change from going through.
You could potentially subscribe to the beforeChange
event and cache a copy of the array before the change. Something like:
self.SourceData.subscribe(function(value) {
/store copy, in case it needs to be restored
self.beforeSourceData = value && value.slice();
}, null, "beforeChange");
回答2:
You can use another approach - create extender to validate your array on change. I've created simplified example that checks simple array of integers for specified upper boundary. Fiddle: http://jsfiddle.net/pkutakov/n2APg/1/ Code:
ko.extenders.checkValue=function (value, condition){
var result=ko.computed({
read: value,
write: function (newValue){
var current=value();
var canSave=true;
ko.utils.arrayForEach(newValue, function(ch) {
if (ch>condition)
canSave=false;
});
if (canSave)
{
value(newValue);
value.notifySubscribers(newValue);
}
else
value.notifySubscribers(value());
}
}).extend({ notify: 'always'});
result(value());
//return the new computed observable
return result;
}
function AppViewModel(data)
{
self=this;
self.Data=ko.observableArray(data).extend({ checkValue: 100});
}
var mydata=[10, 11];
ko.applyBindings(new AppViewModel(mydata));
来源:https://stackoverflow.com/questions/20691374/how-might-i-cancel-a-change-to-an-observable-array-w-knockout-3-0