Move validation from observable to computed

杀马特。学长 韩版系。学妹 提交于 2019-12-13 00:48:15

问题


I have a custom KO extension that formats numbers, this extender wraps the original observable in a computed and return the new reference to the computed.

There is a problem, lets say down the chain before the number extender is called someone adds a validation to the observable, then this validation will not work when the computed is exposed by the number extender.

Can I somehow move the validation from the observable to the computed?

Off course I can make sure that the validation is added after the number extender, but that does not feel very solid, especially not in a large project

The extender looks like

ko.extenders.asNumber = function (target) {
    var result = ko.computed({
        read: function () {
            return Globalize.format(target(), "N2");
        },
        write: function (value) {
            if (value != null && value.substr) {
                var parsedValue = Globalize.parseFloat(value);
                if (isNaN(parsedValue)) {
                    parsedValue = value;
                }
                value = parsedValue;

                if (!String.hasValue(value))
                    value = null;
            }

            target(value);
            target.valueHasMutated();
        }
    });

    target.hasValue = function () {
        return target() != null && target() != 0;
    };
    result.raw = target;
    return result;
};

update:

One way of solving it is

function copyValidation(observable, newObservable) {
    if (observable.__valid__) {
        newObservable.extend({ validatable: true });
        ko.utils.arrayForEach(observable.rules(), function(rule) {
            newObservable.rules.push(rule);
        });
        observable.rules([]);
    }
}

Final version

If no one has a better way I will go for this

function moveValidation(observable, newObservable) {
    if (observable.__valid__) {
        newObservable.extend({ validatable: true });
        ko.utils.arrayForEach(observable.rules(), function(rule) {
            newObservable.rules.push(rule);
        });
        observable.extend({ validatable: false });
    }
}

update

Above solution with observable.extend({ validatable: false }); does for some reason not work once you bundle and minify your scripts. observable.rules([]); works

来源:https://stackoverflow.com/questions/19119826/move-validation-from-observable-to-computed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!