“onlyIf” is frozen on start
I have the "onlyIf" parameter frozen on start in my KnockoutJS validation logic with collections.
.extend({required: {onlyIf: function () {
// ... some Changes Tracking code ...
jsFiddle - frozen onlyIf parameter
Validation doesn't work properly until I manually do resetting for values in all fields with "{required: {onlyIf: function ()" validation rule.
Is this a bug or I miss something?
Taken from my stackoverflow post.
@it3xl Interesting. I can't say exactly why this is happening but I noticed if you comment the following lines of code the validation works.
if (initing && isNew) {
return false;
}
I presume there's some dependency magic in the code which causes this strange behaviour. I will take a look again and see if I can nail this.
@crissdev later I make a workaround. If this would be helpful it looks like this:
a workaround function
var koValidationOnlyIfBugWorkaround = function (observableGetter) {
// Workaround for a knockout-validation's bug! https://jsfiddle.net/it3xl/5zs75yey/
// Without resetting a observable its validation with the "onlyIf" rule doesn't work at all, before value would be changed.
_.defer(function () {
var observable = observableGetter();
var val = ko.unwrap(observable);
observable(val + '-');
observable(val);
});
};
the using of it in a same code:
selfUnit.type = ko.observable(rawObj ? rawObj.type : '')
.extend({required: {onlyIf: function () {
if(initing){
koValidationOnlyIfBugWorkaround(function () { return selfUnit.type; });
}
if(initing && isNew){
return false;
}
var result = unitOrNewChanged(selfUnit);
return result;
}}});
I could not take deeper in the ko-Validation library, sorry ((
_.defer( is http://underscorejs.org/#defer
@it3xl Although this issue is quite old I thought I should give it a look again.
I think this is just a Knockout usage quirk. I've updated your example to write some messages to browser's console and added an observable dependencyHint to help KO detect all the subscriptions it must create.
The problem, IMHO, relies in this piece of code:
selfUnit.type = ko.observable(rawObj ? rawObj.type : '')
.extend({required: {onlyIf: function () {
// initing && isNew evaluating to true means no dependency
// will be created until unitOrNewChanged(selfUnit) is called
// Call a dummy observable to help KO with the subscriptions
dependencyHint();
if(initing && isNew){
console.warn('No dependency created');
return false;
}
var result = unitOrNewChanged(selfUnit);
console.info('Dependency created');
return result;
}}});
http://jsfiddle.net/5zs75yey/27/