Javascript 在呈现视图后,使用aurelia动态地向页面添加数据

Javascript 在呈现视图后,使用aurelia动态地向页面添加数据,javascript,html,ajax,typescript,aurelia,Javascript,Html,Ajax,Typescript,Aurelia,我正在尝试用aurelia构建一个web应用程序,但在页面上的所有内容都呈现出来之后,我找不到通过AJAX添加数据的方法。场景(简化): 有一个页面,其中一部分是由一个组件(比如说,数据表)动态组成的。数据表有一个标题,表行显示数据。数据表应该通过AJAX调用动态加载数据。我想要的是,在呈现页面后加载数据 我尝试使用Promission,但事实正好相反,也就是说,aurelia会等到Promission解决后再附加视图(Jeremy Danyow也解释道:“……在本例中,aurelia会等到ac

我正在尝试用aurelia构建一个web应用程序,但在页面上的所有内容都呈现出来之后,我找不到通过AJAX添加数据的方法。场景(简化):

有一个页面,其中一部分是由一个组件(比如说,数据表)动态组成的。数据表有一个标题,表行显示数据。数据表应该通过AJAX调用动态加载数据。我想要的是,在呈现页面后加载数据

我尝试使用Promission,但事实正好相反,也就是说,aurelia会等到Promission解决后再附加视图(Jeremy Danyow也解释道:“……在本例中,aurelia会等到activate方法返回的Promission解决后,再将视图绑定到viewmodel。”(在他标题为“ES7与Aurelia异步/等待”) 这会导致页面保持暂停状态,直到加载所有数据

下面提供了一个简单的代码示例。在这里,如果您导航到此页面,在加载所有数据之前,您将看不到任何内容(或者该页面不会被附加)。我想要的是,加载该页面并显示“Table for…”。。。标题,同时在后台开始加载数据,并在加载完成时显示表本身。下面的“模拟”屏幕截图说明了所需的行为

此外,可能需要根据用户选择更新表(可能会加载附加数据并将其添加到表中),或者可能需要将附加表添加到页面中

我认为期望的行为与任何绑定/附加/分离等生命周期行为都不匹配(但可能是错误的)。这可以使用body.onload(或jquery等)的变体来实现,但我想知道是否可以仅使用aurelia(或大部分使用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.html

<template>
  <h2>Table for ${id}</h2>

  <div repeat.for="rows of tableData">${rows}</div>
</template>

${id}的表
${rows}
加载器

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
  }
}
导出类加载器{
静态加载数据(tid):承诺{//模拟真实数据加载的简单存根
let数据:编号[][]=[]
开关(tid){
案例1:
data.push([11,12,13])
data.push([14,15,16])
打破
案例2:
data.push([21,22,23])
data.push([24,25,26])
打破
案例3:
data.push([31,32,33])
data.push([34,35,36])
打破
}
这个
返回新承诺((解决、拒绝)=>{
这个
解析(数据)
})
}
受保护的静态睡眠():布尔{//仅用于模拟加载时间
设毫秒=Math.floor(Math.random()*(3-1+1)+1);
var currentTime=new Date().getTime();
调试(“等待一秒:“+毫秒”)
而(currentTime+毫秒*1000>=新日期().getTime()){
}
返回真值
}
}

编辑:更正了此处示例中误传的代码

您应该尝试使用
窗口。超时
模拟加载时间。由于Javascript是单线程的,因此睡眠函数将阻止线程上的所有其他执行


这个答案可能有点过头了,但更详细地解释了如何用javascript编写睡眠函数:

您不能使用
作为自定义元素,而不是使用
组合
?-即
;注意,您需要使用
id
以外的其他名称,因为它们是html为快速响应保留了感谢。不幸的是,同样的情况也发生了(即,所有内容都已加载,因此页面在所有数据加载完成之前,在显示任何内容之前都会暂停)还有自定义元素。嗯……你能做一个JSFIDLE什么的吗?我认为不应该发生这种情况,所以我想知道问题出在哪里。首先,你应该尝试使用
window.timeout
来模拟加载时间。你的睡眠函数将阻止所有其他执行。另外,
。然后((res)=>{this.tableData=res})
替换对aurelia可能无法获取的tableData的引用。请尝试修改现有数组,删除现有项,并在所有响应的hanks中添加新项。@dpix确实,睡眠是罪魁祸首,因为它阻止了js的单线程执行(我错误地假设promise的行为像一个go例程!),因此这不是模拟加载的正确方法。最后,编写了一个简单的http服务进行测试,它成功了。只需注意,aurelia能够在加载数据时更新视图时拾取
this.tableData=res
。最后,问题的问题不是关于aurelia和ajax,那么我应该怎么做?以某种方式关闭它?它似乎我不能接受你的评论作为回答,因为这是一个评论
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
  }
}