5

我目前有两个 Knockout 扩展功能。一个向 Observable 添加一个成员,而另一个拦截读取和写入操作。

组合扩展方法时,应用程序的顺序会产生不良影响。

下面的简化代码示例。

ko.extenders.format = function(target) {
    var result = ko.computed(function(){
        return "$" + target();
    });

    target.formatted = result;

   return target;
};

ko.extenders.numeric = function(target, precision) {
    var result = ko.computed({
        read: function() {
            var current = parseFloat(target());
           return current.toFixed(precision);
        },
        write: function(newValue) {
            newValue = parseFloat(newValue);
            target(newValue.toFixed(precision));
        }
    });

    return result;
};

在数字方法中,我可以检查格式化成员并将其分配给新计算的成员,但我不想让它知道其他方法。如果我决定从 observable 或扩展中添加更多成员,这也将无法维护。

if(target.hasOwnProperty("formatted")){
    result.formatted = target.formatted;
}

这是一个没有 hasOwnProperty 修复的小提琴。 http://jsfiddle.net/gs5JM/2/

请注意 MyValue4 - Format: 由于扩展程序应用程序的顺序和格式化成员的丢失,因此为空白。

是否有更好的模式来实现相同的最终结果并使代码更灵活?

4

1 回答 1

1

问题是你的format扩展器引用了原始的 observable 并numeric创建了一个新的。因此formatnumeric使用完全不同的 observables。看起来你应该考虑在这两种情况下都返回原始的 observable。

我会这样重写你的numeric

ko.extenders.numeric = function(target, precision) {

    ko.computed(function(){
        var current = parseFloat(target());
        target(isNaN(current) ? 0 : current.toFixed(precision));
    });

    return target;
};

Anonymous将通过立即评估创建对价值变化computed的订阅。target评估函数将尝试解析一个值并将精确的数值重新分配给目标 observable。

http://jsfiddle.net/gs5JM/3/

注意:您不应该关心可能的循环依赖,因为 KOcomputed在它已经在评估时不会重新评估

于 2013-10-22T06:23:58.993 回答