2017-01-30 3 views
0

По-прежнему пытаюсь найти ответ Aurelia JS - Making a synchronous HTTP request, to change data before page load? - так что я уменьшил его до следующего вопроса.Aurelia - как изменить связанные переменные, поэтому графический интерфейс меняется?

Скажем, мы работаем с менеджера контактов урока:

... чей код также копируется на https://gist.run/?id=c73b047c8184c052b4c61c69febb33d8 ...

Теперь, это то, как я прочитал код: в contact-list.js, в constructor() от ContactList класс, у нас есть:

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

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

... так что в конструкторе this.contacts класса ContactList инициализируется пустым массивом.

Затем, в том же 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' : ''}"> 
    ... 

... который по-видимому перебирает this.contacts класса ContactList и делает <li> (и другие) элементы в HTML GUI на основе этого.

Так что, как я понимаю это, идея состоит в том, что всякий раз, когда this.contacts свойства ContactList класса изменилось, то <li repeat.for="contact of contacts" ... должен выполнить еще раз, и показать обновленный графический интерфейс в соответствии с данными.

Однако я не могу это продемонстрировать. Самый простой, я думал, будет иметь функцию выполнить несколько секунд после того, как created() метод ContactList побежал, так что я пытался использовать 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); 
    } 

Таким образом, это только простое назначение this.contacts из ContactList класса в новый массив данных.

Итак, для этого я действительно получаю окно предупреждения через несколько секунд; он говорит «changeContactList done 1», что означает, что массив this.contacts действительно был изменен на новые данные - кроме, никаких изменений вообще нет в графическом интерфейсе ?!

Так что я делаю неправильно? Должен ли я использовать дополнительную функцию для обновления состояния? Но если мне нужно вызвать дополнительную функцию, то какова точка привязки? Другими словами, что мне нужно сделать, чтобы обновить графический интерфейс и показать вновь измененное состояние массива 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); 
    } 
Смежные вопросы