2013-04-25 194 views
1

我得到的错误,当ko.mapping更新我的模型,其中有一些订阅。一旦订阅被删除,一切就像魅力一样。任何想法如何使其工作?ko.mapping:与订阅更新模型

考虑这个例子(jsfiddle available) - 呼吁ko.mapping.fromJS()initModel()触发错误:

var iniData = { 
    FirstName: "foo", 
    LastName: "bar" 
}; 

var PersonModel = function() { 
    this.FirstName = ko.observable(""); 
    this.LastName = ko.observable(""); 
    this.FullName = ko.observable(""); 

    // If you comment out subscribe() calls, everything works fine! 
    this.FirstName.subscribe(this.updateFullName);  
    this.LastName.subscribe(this.updateFullName); 


    // Update FullName only if it's empty 
    this.updateFullName = function(){ 
      if (!this.FullName()) { 
       this.FullName(
        this.LastName() + 
          this.FirstName() ? (
           " " + this.FirstName() 
          ):'' 
       ); 
      } 

     }; 
    this.initModel = function(){ 
     try { 
     ko.mapping.fromJS(iniData, {}, this); 
     } 
     catch(err) { 
      alert(err.message); 
     } 
    } 
} 

ko.applyBindings(new PersonModel()); 

回答

1

updateFullName功能应该放在两个订阅你在做之前,否则此方法是尚未被称为JavaScript解释器。就像这样:

var self = this; 
    self.FirstName = ko.observable(""); 
    self.LastName = ko.observable(""); 
    self.FullName = ko.observable(""); 

    // Update FullName only if it's empty 
    self.updateFullName = function(){ 
      if (!self.FullName()) { 
       self.FullName(
        self.LastName() + 
          self.FirstName() ? (
           " " + self.FirstName() 
          ):'' 
       ); 
      } 

     }; 

    // If you comment out subscribe() calls, everything works fine! 
    self.FirstName.subscribe(self.updateFullName);  
    self.LastName.subscribe(self.updateFullName); 

另外,我觉得你的情况,你应该避免订阅和申报FullName作为计算观察到的,其实这是完美的情况。以下是如何做到这一点:

self.FirstName = ko.observable(""); 
self.LastName = ko.observable(""); 
self.FullName = ko.computed(function() { 
    return self.LastName() + (self.FirstName() ? " " + self.FirstName() : ""); 
}; 

每当东西FirstNameLastName计算的FullName观察的更新变化。


编辑:我查过你的小提琴,这是错误的另一件事是,updateFullName功能中的“本”指的是方法,不是你的视图模型的上下文的上下文。这就解释了为什么没有找到fullName财产。检查更新的fiddle

+0

你明白了!当然我应该在提到它之前宣布更新函数。 – 2013-04-25 17:37:45

+0

对了,还要看看我的小提琴,你应该始终声明另一个变量引用您的视图模型,如“自我”。因为“this”可能并不总是指向你的视图模型。见http://joshuakehn.com/2011/10/20/Understanding-JavaScript-Context.html – Jalayn 2013-04-25 17:42:28

+0

确实使用'self'更安全。另一个选择是提供'this'值作为'subscribe'的第二个参数,就像在http://jsfiddle.net/y48U2/3/ – 2013-04-25 18:37:50

0

不计算一个观察到更有意义吗?或者,fullName值是否必须自己编辑?

[编辑]哎呦,Jalayn更快;)

+0

中一样,我想允许修改FullName,因此使用订阅(代码是稍微简化一下,因为只要提供一个First/Last名字,它就会停止更新FullName ... 但是无论如何,我的问题适用于更广泛的范围:ko.mapping.toJS将无法更新ANY模型订阅我想知道正确的方式来设计它。 – 2013-04-25 17:25:52