2015-06-23 39 views
1

比方说,我希望有行为的ko.computed有:是否有可能将ko.computed继承到原型类?

  • 阅读

,但我希望有一个内部观察的是ko.computed属性里面,例如:

this.a = ko.computed(function() { 
    value: ko.observable(null), 

    read: function() { 
     return value; 
    }, 

    write: function(newValue) { 
     if (newValue) { 
      value(newValue); 
     } 
    } 
}); 

这是可能的某种方式?上述不起作用。

+0

您是否在寻找扩展 http://knockoutjs.com/documentation/extenders.html –

+0

你能解释一下你的意思*”继承ko.computed到原型类“*? – Tomalak

+1

你应该更新你的标题,我的答案更多是针对标题“继承ko.computed到原型类” – Anders

回答

2

它看起来像你想要的是一个可观察的,不允许验证失败的分配。你可以做到这一点与普通观察到的一个扩展:

ko.extenders.constrain = function (target, option) { 
    var lastValidValue = target(); 
    target.subscribe(function (newValue) { 
     if (option(newValue)) { 
      lastValidValue = newValue; 
     } else { 
      target(lastValidValue); 
     } 
    }); 
    return target; 
}; 

调用它像这样以防止falsy值的分配:

var notFalsy = ko.observable("Bob").extend({ 
    constrain: function (newValue) { 
     return newValue; 
    } 
}); 

更新:这是可能显著,上述方法确实允许纠正之前的任务。如果重要的是观察值永远不会取无效值,那么可以使用一个计算结构(非常像Anders的解决方案)。

function constrainedObservable(constraint) { 
    var value = ko.observable(); 
    return ko.computed({ 
     read: value, 
     write: function (newValue) { 
      if (constraint(newValue)) { 
       value(newValue); 
      } 
     } 
    }); 
} 

演示http://jsfiddle.net/o641v37L/1/(取消注释分配使用计算)

+0

第一个codeblock中的'return target;'语句是否用于除链之外的任何其他目的? – Tyblitz

+0

@Tyblitz我不确定它有任何用途。我认为这是为了在任务期间进行链接,但是我把它拿出来,并且分配工作也是一样的。 http://jsfiddle.net/o641v37L/ –

3

你可以做,

http://jsfiddle.net/b5stgh3L/

var myComputed = function() { 
    var value = ko.observable(); 

    return ko.computed({   
     read: function() { 
      return value(); 
     }, 
     write: function(newValue) { 
      if (newValue) { 
       value(newValue); 
      } 
     } 
    })  
}; 

var vm = function() { 
    this.my = myComputed(); 
}; 

var instance = new vm(); 

instance.my("value"); 
instance.my(null); 

console.log(instance.my()); 

您还可以延长使用原型计算,像KO用它internaly

function setPrototypeOf(obj, proto) { 
    obj.__proto__ = proto; 
    return obj; 
} 

使用喜欢(ko.utils.setPrototypeOf不会导出使用以上代码)

ko.utils.setPrototypeOf(ko.observableArray['fn'], ko.observable['fn']); 

我发现这里的老答案可以probaly帮助你如何使用approuch

How can I create a typed collection class in Knockout mapping?

http://jsfiddle.net/xop2go2z/

+0

好的+1。!欢呼队友 –

+1

顺便说一句,myComputed函数可以很容易地转换为扩展函数http://jsfiddle.net/b5stgh3L/1/ – Anders

+0

@Anders您的扩展是一个相当复杂的空操作。它从字面上什么都不做。 – Tomalak

2

这不正是问题的重复回答了在这里https://stackoverflow.com/a/30506199/18771的原型,但它是非常关。底线是,不,你实际上不可能在你的原型链中有一个计算,因为计算的结果将在你所有的视图模型实例之间共享。

如果在多个对象实例之间共享一个计算单元是您打算执行的操作,请继续。

如果你想创建某种类的层次结构,但仍然希望你的个人viewmodel实例有自己的独立观察对象,那么你不能通过原型来完成。背景:JavaScript既没有类(抽象对象描述),也没有基于类的继承(分层抽象对象描述)。 JavaScript有对象(由构造函数产生)和原型链(单个链接的对象列表)。原型链中的所有东西在由对象构造函数创建的所有实例之间物理共享。

+0

+1回答'字面上'问的问题。在你关于JS没有类的笔记上:这会改变结构与ES6还是只是语法糖? – Tyblitz

+0

@Tyblitz句法糖。 – Tomalak