2013-11-20 160 views
1

很抱歉,如果之前已經詢問過這個問題,但經過大量搜索後,我似乎無法找到明確解決我的情況的答案。Javascript繼承:從超類的方法設置子類的屬性

我有一個超類,我們將調用窗體,它有一些通用的方法。我只關注兩種特定的方法。 show_form()顯示錶格,load_token()從服務器獲取令牌。

形式

function Form() { 
    // Event handler for form submission 
    this.submit_button.bind('click', jQuery.proxy(function(){ 
    this.submit(); 
    }, this)); 
} 

Form.prototype.show_form = function() { 
    // Some other stuff happens here, but this is the relevant part. 
    // We load the token 
    this.load_token(); 
} 

Form.prototype.load_token = function(){ 
    // Contains a synchronous ajax request that fetches the token from the server 
    // and sets it. So we end up with 
    this.token = 'some-token'; 
}; 

然後,我有一個子類叫做EmailForm,從表繼承。我還爲這個類定義了一個自定義的submit()方法,該方法由Form()的構造函數中的事件處理函數調用。所以,我有:

EmailForm

function EmailForm() {}; 
EmailForm.prototype = new Form(); 

EmailForm.prototype.submit = function() { 
    console.log(this.token); // Returns undefined 
}; 

最後,這裏是這一切是如何走到一起

$('#email_form_link').bind('click', function(){ 
    var email_form = new EmailForm(); 
    email_form.show_form(); 
}); 

問題

所以我需要的令牌向服務器發出請求。由於有幾種形式需要使用load_token()方法,所以我在超類中定義它,並讓子類繼承它。由於我打電話email_form.show_form(),我預計email_formtoken屬性會被設置,但這似乎並不是這樣。

那麼我怎樣才能調用一個從超類繼承的方法,並讓它改變調用它的子類的屬性呢?

+1

你肯定根本問題」不是個t與異步操作不是c在代碼檢查結果(令牌被設置)之前完成? – Pointy

+0

對不起,忘了提。這實際上是一個同步請求。 –

+0

好的,你怎麼知道'.show_form()'在「submit」函數運行之前被調用?你知道(通過'console.log()'或其他什麼)'.load_token()'發生? – Pointy

回答

0

您可以嘗試使用關鍵字this定義方法,而不是使用對象的prototype。當然,這意味着每個新對象都將獲得它自己的方法實例(更多內存),而不是「繼承」或共享同一個實例,但是這樣,每個對象(子類EmailForm的)都會擁有它自己的屬性token設置。

Ex。

http://jsfiddle.net/64RRY/1/

0

http://api.jquery.com/bind/

在jQuery 1.7中,。對()方法是事件處理程序的 附着於文檔的首選方法。

如果你想爲每一個形式的令牌比問題可能是由異步請求引起的,當你請求值時沒有返回一個值(我沒有看到異步代碼或請求值的代碼令牌)

Form.prototype.load_token = function(){ 
    var me = this; 
    $.get("ur").then(function(data){ 
    me.token = 'some-token'; 
    }//,fail function here 
); 
}; 

如果你想標記被設置一次,它的價值,爲以後創建的每個EmailForm或表格項目共享:

$.get("url")then(function(data){ 
    Form.prototype.token = data.token; 
});