在渲染视图/模板之前,等待Angular 2加载/解析模型

在渲染视图/模板之前,等待Angular 2加载/解析模型,angular,promise,observable,dependency-resolver,Angular,Promise,Observable,Dependency Resolver,在Angular 1.x中,UI路由器是我的主要工具。通过返回“解析”值的承诺,路由器只需等待承诺完成,然后再呈现指令 或者,在Angular 1.x中,空对象不会使模板崩溃-因此,如果我不介意临时不完整的渲染,我可以在承诺之后使用$digest进行渲染。然后()填充最初为空的模型对象 在这两种方法中,如果可能的话,我更愿意等待加载视图,如果无法加载资源,则取消路线导航。这让我省去了“取消导航”的工作。编辑:注意,这特别意味着该问题要求使用Angular 2 futures兼容或最佳实践方法,并

在Angular 1.x中,UI路由器是我的主要工具。通过返回“解析”值的承诺,路由器只需等待承诺完成,然后再呈现指令

或者,在Angular 1.x中,空对象不会使模板崩溃-因此,如果我不介意临时不完整的渲染,我可以在
承诺之后使用
$digest
进行渲染。然后()
填充最初为空的模型对象

在这两种方法中,如果可能的话,我更愿意等待加载视图,如果无法加载资源,则取消路线导航。这让我省去了“取消导航”的工作。编辑:注意,这特别意味着该问题要求使用Angular 2 futures兼容或最佳实践方法,并要求尽可能避免使用“Elvis运算符”!因此,我没有选择这个答案

但是,这两种方法都不适用于Angular 2.0。当然,有一个标准的解决方案计划或可用于此。有人知道这是什么吗

@Component() {
    template: '{{cats.captchans.funniest}}'
}
export class CatsComponent {

    public cats: CatsModel;

    ngOnInit () {
        this._http.get('/api/v1/cats').subscribe(response => cats = response.json());
    }
}

以下问题可能反映了相同的问题:。请注意,问题中没有代码或已接受的答案。

在您的
@组件中执行
激活
,并返回您的承诺:

编辑:这显然不起作用,尽管当前文档对此主题可能有点难以解释。更多信息,请参见Brandon的第一条评论:

编辑:通常准确的Auth0网站上的相关信息不正确:


编辑:angular团队正为此计划一个@Resolve装饰器。

尝试
{{model?.person.name}
这应该等待模型不
未定义
,然后进行渲染

Angular 2将此
?。
语法称为。在文档中很难找到对它的引用,因此这里有一份副本,以防他们更改/移动它:

Elvis运算符(?)和null属性路径

角度“Elvis”运算符(?)是防止属性路径中出现空值和未定义值的流畅且方便的方法。在这里,如果currentHero为空,则可以防止视图渲染失败

当前英雄的名字是{{currentHero?.firstName}}

让我们详细说明这个问题和这个特殊的解决方案

当以下数据绑定标题属性为null时会发生什么情况

标题为{{title}

视图仍然渲染,但显示值为空;我们只看到“标题是”,后面什么也没有。这是合理的行为。至少应用程序没有崩溃

假设模板表达式包含一个属性路径,如下一个示例中所示,我们将显示一个空英雄的名字

空英雄的名字是{{nullHero.firstName}}

JavaScript抛出空引用错误,Angular也抛出空引用错误:

TypeError:无法读取[null]中null的属性“firstName”

更糟糕的是,整个视图消失了

如果我们相信英雄属性永远不能为空,那么我们可以声称这是合理的行为。如果它永远不能为null,但它仍然为null,那么我们就犯了一个编程错误,应该捕获并修复它。抛出异常是正确的做法

另一方面,属性路径中的空值有时也可以,特别是当我们知道数据最终会到达时

当我们等待数据时,视图应该毫无怨言地呈现,空属性路径应该像title属性一样显示为空

不幸的是,当currentHero为空时,我们的应用程序崩溃

我们可以用NgIf解决这个问题

空英雄的名字是{{nullHero.firstName}}

或者我们可以尝试用&&链接属性路径的部分,知道表达式在遇到第一个null时退出

空英雄的名字是{{nullHero&&nullHero.firstName}

这些方法有其优点,但可能会很麻烦,特别是当属性路径很长时。想象一下,在长属性路径(如a.b.c.d)中的某个地方防范null

角度“Elvis”操作符(?)是防止属性路径中出现空值的更流畅、更方便的方法。表达式在遇到第一个空值时退出。显示为空白,但应用程序继续运行,没有错误

空英雄的名字是{{nullHero?.firstName}}

它也适用于长属性路径:

a?.b?.c?.d


使用观察者设置局部值

…此外,不要忘记使用虚拟数据初始化值,以避免
未初始化的
错误

export class ModelService {
    constructor() {
      this.mode = new Model();

      this._http.get('/api/v1/cats')
      .map(res => res.json())
      .subscribe(
        json => {
          this.model = new Model(json);
        },
        error => console.log(error);
      );
    }
}
该模型是表示数据结构的数据模型

没有参数的模型应该创建一个新实例,其中所有值都已初始化(但为空)。这样,如果模板在接收数据之前呈现,则不会抛出错误


理想情况下,如果您希望持久化数据以避免不必要的http请求,您应该将其放入一个对象中,该对象有自己的观察者,您可以订阅。

编辑:angular团队已经发布了@Resolve decorator。它仍然需要一些澄清,说明它是如何工作的,但在此之前,我将在这里接受其他人的相关回答,并提供指向其他来源的链接:


编辑:此答案仅适用于Angular 2 BETA。截至本次编辑,角2 RC的路由器未发布。相反,当使用Angular 2 RC时,将对
路由器的引用替换为
路由器已弃用
,以继续使用beta路由器

安格尔
@CanActivate((to) => {
    return new Promise((resolve) => {
        to.routeData.data.user = { name: 'John' }
class Backend {
  fetchTeam(id: string) {
    return 'someTeam';
  }
}

@Injectable()
class TeamResolver implements Resolve<Team> {
  constructor(private backend: Backend) {}

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<any>|Promise<any>|any {
    return this.backend.fetchTeam(route.params.id);
  }
}

@NgModule({
  imports: [
    RouterModule.forRoot([
      {
        path: 'team/:id',
        component: TeamCmp,
        resolve: {
          team: TeamResolver
        }
      }
    ])
  ],
  providers: [TeamResolver]
})
class AppModule {}
  // the no-observable method
  this.dataYouResolved= this.route.snapshot.paramMap.get('id');
  // console.debug(this.licenseNumber);

  // or the observable method
  this.route.paramMap
     .subscribe((params: ParamMap) => {
        // console.log(params);
        this.dataYouResolved= params.get('id');
        return params.get('dataYouResolved');
        // return null
     });
  console.debug(this.dataYouResolved);
<div *ngIf="vendorServicePricing && quantityPricing && service">
 ...Your page...
</div