Aurelia-如何更改绑定变量,以便GUI更改? [英] Aurelia - how to change bound variables, so the GUI changes?
问题描述
Still trying to find an answer to Aurelia JS - Making a synchronous HTTP request, to change data before page load? - so I've reduced it to the following question.
假设我们与联系人管理器教程一起工作:
Let's say we work with contact manager tutorial:
......其代码也复制在 https://gist.run/?id=c73b047c8184c052b4c61c69febb33d8 ...
... whose code is also copied on https://gist.run/?id=c73b047c8184c052b4c61c69febb33d8 ...
现在,这就是我阅读代码的方式:在contact-list.js
中,在ContactList
类的constructor()
中,我们有:
Now, this is how I read the code: in contact-list.js
, in the constructor()
of ContactList
class, we have:
export class ContactList {
static inject = [WebAPI, EventAggregator];
constructor(api, ea){
this.api = api;
this.contacts = [];
...
...因此在构造函数中,ContactList
类的this.contacts
被初始化为一个空数组.
... so in the constructor, this.contacts
of the ContactList
class is initialized to an empty array.
然后,在同一ContactList
类中,有一个created()
方法:
Then, in the same ContactList
class, there is a created()
method:
created(){
this.api.getContactList().then(contacts => this.contacts = contacts);
}
这将检索web-api.js
中定义的联系人列表,并将其分配给以前为空的类ContactList
属性this.contacts
.
This retrieves the contact list as defined in web-api.js
, and it assigns it to the class ContactList
property this.contacts
, which was previously empty.
最后,在contact-list.html
中,我们有:
<li repeat.for="contact of contacts" class="list-group-item ${contact.id === $parent.selectedId ? 'active' : ''}">
...
...显然遍历类ContactList
的this.contacts
,并基于此在HTML GUI中创建<li>
(及其他)元素.
... which apparently iterates through this.contacts
of the class ContactList
, and makes <li>
(and other) elements in the HTML GUI based on that.
因此,据我所知,其思想是,每当ContactList
类的this.contacts
属性发生更改时,<li repeat.for="contact of contacts" ...
都应再次执行,并根据数据显示更新的GUI.
So, as I understand this, the idea is that whenever the this.contacts
property of the ContactList
class changed, then the <li repeat.for="contact of contacts" ...
should execute again, and show an updated GUI in accordance with the data.
但是,我无法证明这一点.我认为最简单的方法是在ContactList
的created()
方法运行后几秒钟执行一个函数,因此我尝试使用setTimeout
来实现这一目的:
However, I cannot get to demonstrate this. The easiest, I thought, would be to have a function execute a few seconds after the created()
method of ContactList
has run, so I tried to use setTimeout
for that:
created(){
this.api.getContactList().then(contacts => this.contacts = contacts);
setTimeout(this.changeContactList, 3000); // call changeContactList() function after 3 seconds
}
...并且我添加了一个changeContactList
方法,即:
... and I've added a changeContactList
method which is this:
changeContactList() {
this.contacts = [ {
id:13,
firstName:'Bob',
lastName:'Rock',
email:'bob@rock.com',
phoneNumber:'888-7303'
}
];
alert("changeContactList done " + this.contacts.length);
}
所以,这只是将ContactList
类的this.contacts
分配给新数据数组的简单分配.
So, it is just a simple assignment of this.contacts
of the ContactList
class to a new data array.
因此,我确实在几秒钟后得到了一个警报窗口;它的确显示为"changeContactList done 1
",这意味着this.contacts
数组确实已更改为新数据-除非GUI中没有任何更改?!
So, for this, I do indeed get an alert window after some seconds; it does say "changeContactList done 1
" meaning that the this.contacts
array has indeed been changed to the new data - except, there are no changes whatsoever in the GUI?!
那么我在做什么错了?我是否应该调用附加功能以呈现更新的状态?但是,如果我必须调用附加函数,那么绑定的目的是什么?换句话说-我该怎么做才能使GUI更新并显示this.contacts
阵列的新更改状态?
So what am I doing wrong? Am I supposed to call an additional function to have the updated state render? But if I have to call an additional function, what is the point of binding, then? In other words - what do I have to do, to get the GUI to update and show the newly changed state of the this.contacts
array?
推荐答案
好吧,发现了问题所在-上面代码的问题是,当您使用setTimeout
时,this
的含义发生了变化-在这种情况下,this
成为对Window
的引用,而不是对定义类的实例的引用! (其余绑定显然按照我之前的理解起作用)
Ok, found what the problem is - the problem with the code above is that the meaning of this
changes when you use setTimeout
- in that case, this
becomes a reference to Window
, not to an instance of the defining class! (the rest of the binding apparently works as I had understood it previously)
考虑到这一点,我终于有了GUI来显示更新的数据数组,并在contact-list.js
中进行了以下更改:
With that in mind, I finally got the GUI to show the updated data array with the following changes in 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:'bob@rock.com',
// 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:'bob@rock.com',
phoneNumber:'888-7303'
});
alert("changeContactList done " + this.contacts.length);
}
这篇关于Aurelia-如何更改绑定变量,以便GUI更改?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!