2012-11-18 58 views
0

請問有人可以幫我嗎?Knockout - 如何從嵌套函數訪問父屬性?

*Uncaught TypeError: Object #<Object> has no method 'baseUri'* 

這種方法是從下面的結合稱爲:

<form id="createProducts" data-bind="submit: products.create"> 

讀取執行方法

執行創建方法時,我發現了以下錯誤,從PreOoad方法調用,均爲baseUri項目可用。

當視圖模型被定義爲一個函數時,我發現這個問題的解決方案,但在我的情況下,它被定義爲一個對象。

這是我的全部JS文件


var mm = { 

    /* Products ********************************************************** */ 

    products: { 

     items: ko.observableArray([]), 

     read: function() { 
      $.getJSON(this.baseUri(), this.items); 
     }, 

     create: function (formElement) { 

      $.post(this.baseUri(), $(formElement).serialize(), null, "json") 
       .done(function (o) {      
        alert("The Product " + o.Name + " was created."); 
        this.items.push(o); 
       }); 
     }, 

     baseUri: function() { return BASE_URI; } 
    } 

}; 

function PreLoad() { 

    mm.products.read(); 

    ko.applyBindings(mm); 
} 

  • BASE_URI是我的母版頁中定義一個全局變量,我需要它,因爲我有多個嵌套的視圖模型(我從這段代碼中刪除它們),每個baseUri都是BASE_URI +「some_string_value」的組合。無論如何,我還需要訪問,以便更新列表中顯示的值。

謝謝!

回答

0

有兩種方法可以確保this在綁定事件時是正確的。

首先是使用bind

<form id="createProducts" data-bind="submit: products.create.bind(products)"> 

二是使用內聯函數:

<form id="createProducts" data-bind="submit: function() { products.create(); }"> 

可能這種行爲將在未來發生變化(見https://github.com/SteveSanderson/knockout/issues/378)。

編輯

有兩種解決方案,以使this提供回調函數。首先是將this複製到一個局部變量,該變量將通過閉包提供。

 var self = this; 
     $.post(this.baseUri(), $(formElement).serialize(), null, "json") 
      .done(function (o) {      
       alert("The Product " + o.Name + " was created."); 
       self.items.push(o); 
      }); 

第二種是在回調函數上使用bind

 $.post(this.baseUri(), $(formElement).serialize(), null, "json") 
      .done(function (o) {      
       alert("The Product " + o.Name + " was created."); 
       this.items.push(o); 
      }.bind(this)); 
+0

謝謝邁克爾!第一個選項部分解決了這個問題。** this.baseUri **是現在可用,但** this.items **是未定義的。也許是因爲它在**。done(函數**。 – TPaim

+0

正確。我已經擴大了答案來處理這個問題。 –

+0

完美的邁克爾!我嘗試,但我把綁定放在錯誤的地方('})。bind'而不是'} .bind')。非常感謝! – TPaim

0

我有一種感覺this是不是你認爲它是當你打電話products.create。嘗試使用.bind明確地設置背景:

<form id="createProducts" data-bind="submit: products.create.bind($data)"> 
+0

嗨,安德魯!我測試了你的建議,但依然如此。 我閱讀了關於這個上下文問題的文章。根據項目5(http://www.knockmeout.net/2011/06/10-things-to-know-about-knockoutjs-on.html),這個代表調用者的上下文。在這種情況下的表單,這就是爲什麼我的函數無法找到項目或baseUri屬性。 – TPaim

+0

該文章建議將「.bind(viewModel)」(我的代碼中的mm)應用於函數,但錯誤仍然存​​在。 – TPaim

+0

如果你使用'.bind($ root)'? –

0

安德魯·惠特克已經提到的 - 「這」將是沒有上下文你期待。我的解決辦法是將存儲的「this」引用(例如所謂的「自我」),並使用它,而不是「本」:

products: { 
    self: undefined, 
    items: ..., 
    init: function() { 
     this.self = this; 
    }, 
    read: function() {$.getJSON(self.baseUri(), self.items);}, 
    create: function() { 
     $.post(self.baseUri(), $(formElement).serialize(), null, "json") 
      .done(function (o) {      
       alert("The Product " + o.Name + " was created."); 
       self.items.push(o); 
      }); 
    }, 
    baseUri: function() { return BASE_URI; } 
}; 

function PreLoad() { 

    mm.products.init(); 
    mm.products.read(); 

    ko.applyBindings(mm); 
} 

你也可以明確指出哪些方面的功能應該被稱爲:

<form id="createProducts" data-bind="submit: function() { products.create($root.products); }"> 

products: { 
    create: function(self) { 
     ... 
    } 

在這種情況下$ root應該指向你的視圖模型,所以你會傳遞產品對象的實例來創建函數。

+0

Hi @Slawek!我很欣賞你的第一個建議,即儘可能簡單地保持html的數據綁定。但不幸的是,錯誤仍然存​​在。 :( 第二個解決了這個問題,但增加了數據綁定的複雜性。今晚我會回到這個項目。謝謝! – TPaim