Asynchronous Aurelia-将repeat.for绑定到从服务器调用填充的计算数组
正如标题所示,我试图将一个元素源绑定到一个计算数组,该数组由http.fetch调用的结果填充。下面是代码(这个问题的有趣部分): 观点:Asynchronous Aurelia-将repeat.for绑定到从服务器调用填充的计算数组,asynchronous,binding,ecmascript-6,httpclient,aurelia,Asynchronous,Binding,Ecmascript 6,Httpclient,Aurelia,正如标题所示,我试图将一个元素源绑定到一个计算数组,该数组由http.fetch调用的结果填充。下面是代码(这个问题的有趣部分): 观点: <tr> <td repeat.for="boardItemFilter of boardItemFilters"> <input if.bind="boardItemFilter.isStringFilter()" type="text" value.bind="boardItemFilter.Valu
<tr>
<td repeat.for="boardItemFilter of boardItemFilters">
<input if.bind="boardItemFilter.isStringFilter()" type="text" value.bind="boardItemFilter.Value & debounce:400" />
<div if.bind="boardItemFilter.isCheckboxFilter()" repeat.for="sourceValue of boardItemFilter.SourceValues">
<input type="checkbox" value.bind="sourceValue" checked.bind="boardItemFilter.SelectedValues" />
<span textcontent.bind="sourceValue"></span>
</div>
</td>
</tr>
其中fetchBoardItemFiltersByUnit()函数为:
fetchBoardItemFiltersByUnit(unitName){
let self = this;
let request = {'unitName': unitName};
return this.http.fetch('BoardFilters',{
method: 'post',
body: json(request),
}).then(response => response.json())
.then(response => this.ExtendFilters(response));
}
所选设备上的boardItemFilters()
计算触发器将正确更改。datacontext调用完成后,该部分工作正常。当aurelia在http.fetch完成之前尝试绑定属性时,就会出现问题。然后,它认为该属性不可重复,并中断。在这些错误之后,console.log(result)
显示服务器返回的预期对象数组,但结果未分配给computed属性。我尝试使用信号行为手动重新触发绑定,但没有成功
问题自然是,我做错了什么?结果是否未存储到computed属性中,或者正在以不期望的方式绑定它?这个问题的正确解决方案是什么
我已经尝试了很多方法,唯一有效的方法是创建一个局部变量来存储http结果,并且总是在promise函数之外返回该变量。但很自然,它将始终返回前一个状态,因为它将运行异步调用,并在调用完成之前返回局部变量。这当然是不能接受的
还是说Aurelia还不支持异步绑定
提前谢谢你
编辑:
我已经设法破解了一个解决方案,但它非常难看(使用promise函数中的bindingSignaler重新绑定,使用newValue和oldValue比较来避免无限计算调用等)。我仍然很想听到实现这一目标的正确方法 这里有一种方法可以解决这种不依赖异步绑定的冗长计算操作:
- 将从属属性从计算属性更改为常规属性
- 手动观察依赖项以调用冗长的操作。仅当冗长的操作完成时,才更新从属属性
export class App {
@bindable count;
constructor() {
this.count = 3;
this.computeNums(this.count)
.then(result => this.nums = result);
}
countChanged(value) {
this.computeNums(value)
.then(result => this.nums = result);
}
computeNums(count) {
let result = [];
for (let i = 1; i <= count; i++) {
result.push(i);
}
return new Promise((resolve, reject) => {
setTimeout(() => resolve(result), 1000);
});
}
}
导出类应用程序{
@可绑定计数;
构造函数(){
这个.计数=3;
这个.计算机(这个.计数)
。然后(result=>this.nums=result);
}
计数已更改(值){
这个。计算(值)
。然后(result=>this.nums=result);
}
计算机(计数){
让结果=[];
for(设i=1;i{
setTimeout(()=>解析(结果),1000);
});
}
}
这里,nums
是根据count
计算的<代码>计算机模拟冗长的操作
观察计数
是通过组合@bindable
和countChanged
实现的。您可能希望改用绑定引擎API,如下所示
可以运行的完整示例:您正在尝试在重复的
的每次迭代中进行http调用。for
,在我看来,这绝对不是一个好方法。你应该重写整个算法。此外,要绑定计算属性,不必使用括号,这if.bind=“boardItemFilter.isStringFilter”
是否足够?我的印象是,我将填充数组一次,然后用repeat.for.对其进行迭代。。你能解释一下吗?编辑:我刚刚查看了网络流量,api只被调用一次,而不是每次迭代..哦,isStringFilter()是一个函数,我用它扩展了filter对象,所以需要括号。。不过,我可以将其转换为计算属性,这样更有意义。谢谢:)对不起!!!我把boardItemFilters
和isStringFilter()
搞得一团糟。他们非常相似,我认为他们是一样的lol。我会再看一遍这个问题,然后我可以分享我的观点。也许这就是你要找的。它仍然是实验性的。不过,我会通过改变逻辑结构而不是依赖某种异步绑定来解决这个问题。谢谢,这对这个案子很有效。
export class App {
@bindable count;
constructor() {
this.count = 3;
this.computeNums(this.count)
.then(result => this.nums = result);
}
countChanged(value) {
this.computeNums(value)
.then(result => this.nums = result);
}
computeNums(count) {
let result = [];
for (let i = 1; i <= count; i++) {
result.push(i);
}
return new Promise((resolve, reject) => {
setTimeout(() => resolve(result), 1000);
});
}
}