2017-01-30 50 views
0

仍試圖找到Aurelia JS - Making a synchronous HTTP request, to change data before page load?的答案 - 所以我將它縮小到以下問題。Aurelia - 如何更改綁定變量,以便GUI更改?

比方說,我們接觸經理完成教程:

...其代碼也被複制在https://gist.run/?id=c73b047c8184c052b4c61c69febb33d8 ...

現在,我這是怎麼讀代碼:contact-list.jsContactList類的constructor(),我們有:

export class ContactList { 
    static inject = [WebAPI, EventAggregator]; 

    constructor(api, ea){ 
    this.api = api; 
    this.contacts = []; 
... 

...所以在構造函數中,ContactList類的this.contacts被初始化爲一個空數組。

然後,在相同ContactList類,有一個created()方法:

created(){ 
    this.api.getContactList().then(contacts => this.contacts = contacts); 
} 

這檢索作爲web-api.js定義的聯繫人列表中,並將其將其分配給類ContactList屬性this.contacts,這是以前空。

最後,在contact-list.html,我們有:

<li repeat.for="contact of contacts" class="list-group-item ${contact.id === $parent.selectedId ? 'active' : ''}"> 
    ... 

...它通過類ContactListthis.contacts顯然迭代,並使得基於該HTML GUI <li>(等)的元素。

所以,我理解這一點,這個想法是,每當ContactList類的this.contacts性質改變,那麼<li repeat.for="contact of contacts" ...應該再次執行,並顯示按照數據更新的GUI。

但是,我無法證明這一點。最簡單的,我認爲,將有ContactListcreated()方法運行後函數執行了幾秒鐘,所以我試圖用爲setTimeout

created(){ 
    this.api.getContactList().then(contacts => this.contacts = contacts); 
    setTimeout(this.changeContactList, 3000); // call changeContactList() function after 3 seconds 
} 

...我已經添加了一個changeContactList方法,該方法是這樣的:

changeContactList() { 
    this.contacts = [ { 
     id:13, 
     firstName:'Bob', 
     lastName:'Rock', 
     email:'[email protected]', 
     phoneNumber:'888-7303' 
    } 
    ]; 
    alert("changeContactList done " + this.contacts.length); 
    } 

因此,它是的ContactList類的this.contacts只是一個簡單的分配給一個新的數據數組。

因此,爲此,幾秒鐘後確實會出現警告窗口;它確實會說「changeContactList done 1」,這意味着this.contacts陣列確實已更改爲新數據 - 除了GUI中沒有任何更改?!

那麼我做錯了什麼?我應該調用一個額外的函數來更新狀態?但是如果我必須調用一個額外的函數,那麼綁定又有什麼意義呢?換句話說 - 我必須做什麼才能讓GUI更新並顯示this.contacts陣列的新變化狀態?

回答

0

好吧,發現問題是什麼 - 上面代碼中的問題是,this變化,當您使用setTimeout的意義 - 在這種情況下,this變得Window參考,不定義類的一個實例! (綁定的休息顯然工程,我以前的理解是)

考慮到這一點,我終於得到了GUI以顯示contact-list.js有以下改動更新後的數據陣列:

created(){ 
    this.api.getContactList().then(contacts => { this.contacts = contacts ; 
     //setTimeout(this.changeContactList, 1000); // timeout delay ok, but 'this' becomes Window 
     //setTimeout(this.changeContactList(this), 1000); // timeout delay not honored here 
     //setTimeout(function() {console.log(this); this.changeContactList(this);}, 1000); // "this.changeContactList is not a function"; 'this' is Window 

     // works OK: 
     //var copythis = this; // make a copy of 'this', since 'this' looses meaning in the setTimeout 
     //setTimeout(function() {console.log(copythis); copythis.changeContactList();}, 1000); // 
    }); 
    console.log(this.contacts); // is empty [] here - Promise unresolved yet 

    // also works OK: 
    var copythis = this; // make a copy of 'this', since 'this' looses meaning in the setTimeout 
    setTimeout(function() {console.log(copythis); copythis.changeContactList();}, 2000); // 
    } 

    changeContactList() { 
    //this.contacts = [ { 
    // id:13, 
    // firstName:'Bob', 
    // lastName:'Rock', 
    // email:'[email protected]', 
    // phoneNumber:'888-7303' 
    //} 
    //]; 
    // "this" is Window here, if called from setTimeout(this.changeContactList, 
    // but if called as setTimeout(this.changeContactList(this), then "this" is ContactList! - but then timeout delay is not honoured 

    console.log(this); 
    console.log(this.contacts); 
    this.contacts.push({ 
     id:13, 
     firstName:'Bob', 
     lastName:'Rock', 
     email:'[email protected]', 
     phoneNumber:'888-7303' 
    }); 
    alert("changeContactList done " + this.contacts.length); 
    }