我正在尝试使用aurelia构建一个Web应用程序,并且在页面上的所有内容都已呈现后,我无法通过AJAX找到添加数据的方法。场景(简化):
有一个页面,其中一部分是由一个组件(比如数据表)动态组成的。 data-table有一个标题,table-rows用来显示数据。 data-table应该通过AJAX调用动态加载它的数据。我想要的是,在呈现页面后加载数据。
我尝试使用promises,但它恰恰相反,即aurelia在附加视图之前等待承诺解决(由Jeremy Danyow解释:" ...在此示例中Aurelia将等待Promise在将视图绑定到viewmodel之前,由activate方法返回以解析。"(在他的帖子标题为" ES7 async / await with Aurelia") 这会导致页面保持停顿状态,直到加载所有数据。
下面提供了一个简单的代码示例。在这里,如果您导航到此页面,则在加载所有数据之前,您将看不到任何内容(或页面不会被附加)。我想要的是,加载页面并显示"表格..."标题,同时开始在后台加载数据并在加载完成时显示表本身。所需的行为在以下" mock"的屏幕截图。
before the ajax requrest is completed
after the ajax request is completed
此外,可能需要根据用户选择更新表格(可能会加载其他数据并将其添加到表格中),或者可能需要将其他表格添加到页面中。
我不认为所需的行为与任何绑定/附加/分离等生命周期行为相匹配(但可能是错误的)。这可以使用body.onload(或jquery等)的变体来实现,但我想知道这是否可以仅使用aurelia(或大部分)。
也许,能够在附加所有内容后加载数据(例如," postattached"回调)可能有所帮助。在这种情况下,我会用已经加载的数据(例如它们的标题)加载所有必要的组件并显示它们。然后,在" postattached"我将开始加载数据。
示例代码:
test.ts
export class testPage {
ids: number[] = [1,2,3] // for example 1,2,3; will be dynamically loaded as well
}
的test.html
<template>
<h1>Test</h1>
<div repeat.for="id of ids">
<compose view-model="./components/table" model.bind="id"></compose>
</div>
</template>
table.ts
import { Loader } from './loader';
export class table {
id: number
tableData: number[][] = []
activate(model) {
this.id = model
}
attached() {
Loader.LoadData(this.id).then((res)=>{this.tableData = res})
}
}
table.html
<template>
<h2>Table for ${id}</h2>
<div repeat.for="rows of tableData">${rows}</div>
</template>
loader.ts
export class Loader {
static LoadData(tid): Promise<number[][]> { //simple stub to imitate real data loading
let data: number[][] = []
switch (tid) {
case 1:
data.push([11, 12, 13])
data.push([14, 15, 16])
break;
case 2:
data.push([21, 22, 23])
data.push([24, 25, 26])
break;
case 3:
data.push([31, 32, 33])
data.push([34, 35, 36])
break;
}
this.sleep()
return new Promise((resolve, reject) => {
this.sleep()
resolve(data)
})
}
protected static sleep(): boolean { // just to imitate loading time
let miliseconds = Math.floor(Math.random() * (3 - 1 + 1) + 1);
var currentTime = new Date().getTime();
console.debug("Wait for a sec: " + miliseconds)
while (currentTime + miliseconds * 1000 >= new Date().getTime()) {
}
return true
}
}
编辑:更正了此处示例的错误代码
答案 0 :(得分:0)
您应该尝试使用window.timeout
来模拟加载时间。因为Javascript是单线程的,所以sleep函数将阻止线程上的所有其他执行。
这个答案可能有点过分,但更详细地解释了如何在javascript中编写睡眠函数:What is the JavaScript version of sleep()?