加载customElements时从activate()返回Promise

pow*_*uoy 3 javascript ecmascript-6 es6-promise aurelia aurelia-router

我知道Aurelia允许我们Promise()从VM的activate()方法返回一个,如果是这样,它将等待承诺解决,然后切换到新视图.

但是,假设我有一个由一个或多个子组件组成的视图,并且它们都发出HTTP请求,我怎么知道所有子组件何时从我的父组件中完成?

额外问题:只有<router-outlet>使用该activate()方法的VM 才是正确的,而用作自定义元素的VM使用该attached()方法是正确的吗?

编辑:稍微详细说明,这是我的一个页面/路线/主要视图可能是什么样子:

<template>
    <main>

        <section id="item">

            <h1>${item.title}</h1>

            <img src="${item.image}">

            <p>${item.description}</p>

            <ul>
                <li repeat.for="si of item.subItems">
                    ${si.subItem}
                </li>
            </ul>

        </section>

        <aside>

            <author-info></author-info>
            <recent-items limit="3"></recent-items>
            <random-quote></random-quote>

        </aside>

    </main>
</template>
Run Code Online (Sandbox Code Playgroud)

我可以轻松地等待${item}加载,然后在主视图的activate方法中解析promise ,但这并不能保证aside已加载的三个子元素.这使它们一个接一个地弹出,看起来不太好.

如果可能的话,我非常想使用Aurelia的内置功能,但我想我可能不得不使用EventAggregator或像Ashley建议的双向绑定来使用我自己的加载器.

很想听听Aurelia团队的人是否有可能这样做?

Mat*_*vis 5

加载路由activate()回调中的所有数据

正如Ashley在上面的评论中指出的那样,最好的策略是加载父路由中的所有数据,并通过绑定将数据推送到自定义元素中.您提到这将导致在包含该元素的每个路由中复制/粘贴代码,但我们可以通过将加载代码移动到服务类并将该类注入到路由中来解决此问题.这样,我们可以保持代码干燥,同时保持代码简单易读.

我们将通过创建<random-quote>自定义元素以及将为我们提供随机引号的服务来演示.

randomQuoteCustomElement.ts

export class RandomQuoteCustomElement {
    @bindable quote: IQuote;
}
Run Code Online (Sandbox Code Playgroud)

randomQuoteCustomElement.html

<template>
  <i>${quote.text}</i>
  <strong>${quote.author}</strong>
</template>
Run Code Online (Sandbox Code Playgroud)

randomQuoteService.ts

export class RandomQuoteService {

  getRandomQuote: Promise<IQuote>() {
    return this.http.fetch('api/quote/random')
      .then((response) => response.json()) 
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

接下来,我们将在视图中包含自定义元素,将服务注入到我们的视图模型中,通过服务获取数据,并使我们的activate()方法依赖于返回的promise.

main.ts

import { RandomQuoteService} from './randomQuoteService';

@inject(RandomQuoteService)
export class MainViewModel {

  quote: IQuote;

  constructor(quotes: RandomQuoteService) {
    this.quotes = quotes;
  }

  activate() {
    return Promise.all([
      this.quotes.getRandomQuote()
        .then((quote) => this.quote = quote)
    ]);
  }
}
Run Code Online (Sandbox Code Playgroud)

main.html中

<template>
  <require from="./randomQuoteCustomElement"></require>
  <random-quote quote.bind="quote"></random-quote>
</template>
Run Code Online (Sandbox Code Playgroud)

因为我们希望我们的activate()函数强烈依赖于结果,所以RandomQuoteService我们需要在activate()回调中直接包含这些代码.我们还可以设计自定义元素以允许绑定数据,但是回退到获取自己的数据,利用相同的服务.

randomQuoteCustomElement.ts

export class RandomQuoteCustomElement {

  @bindable quote;

  constructor(quotes) {
    if (!this.quote) {
      quotes.getRandomQuote()
        .then((quote) => !this.quote && this.quote = quote);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这是一个有效的例子:https://gist.run/?id = c5570192afe5631355efe6b5da3e44b5