如何处理Angular 4中的组件构造函数竞争条件?

时间:2018-01-07 16:13:54

标签: angular asynchronous

我正在尝试使用Angular 4.然而,两个组件构造函数之间的竞争条件似乎阻止了页面正确加载。

我有两个组件 - 一个页面组件和一个嵌套在其中的文章组件。

在页面组件内部,我订阅了一个activatedRoute.queryParams对象,以便在可用时获取“?id = 1”get参数。如果是,我设置页面组件的articleId属性。

import { Injectable, Component } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { ArticleOrm } from '../../../klass/orm/one/articleOrm';
import { Router, ActivatedRoute, Params } from '@angular/router';

@Component({
    selector: 'app-article',
    templateUrl: './article.component.html',
    styleUrls: ['./article.component.css']
})
@Injectable()
export class ArticleComponent {
    articleId;
    constructor(
        private activatedRoute: ActivatedRoute
    ) {
        this.activatedRoute.queryParams.subscribe((params) => {
            this.articleId = params.id;
        });
    }
}

在页面组件视图文件中,我包含了文章模块本身的组件,并将收集的articleId作为输入参数传递。

<div class="com-article">
    <single-article [articleId]="articleId"></single-article>
</div>

在文章组件中,构造函数创建一个新文章ORM对象。这是一个定制的ORM解决方案。调用this.article.get()会返回一个RxJS observable,我相信。

import { Input, Injectable, Component } from '@angular/core';
import { ArticleOrm } from '../../../klass/orm/one/articleOrm';
import { HttpClient, HttpHeaders } from '@angular/common/http';

@Component({
    selector: 'single-article',
    templateUrl: './singleArticle.component.html',
    styleUrls: ['./singleArticle.component.css']
})
@Injectable()
export class SingleArticleComponent {
    @Input() articleId;
    article: ArticleOrm;
    constructor(
        private http: HttpClient
    ) {
        var scope = this;
        this.article = new ArticleOrm(this.articleId, {
            http: scope.http
        });
        var observable = this.article.get();
    }
}

Orm类看起来像这样......

export class ArticleOrm {
    ...
    get() {
        let fullUrl = this.getUrl + '?id=' + this.identifier;
        var obs = this.http.get(fullUrl);
        obs.subscribe((res) => {
            this.properties = res.response;
            this.identifier = res.response.id;
        });
        return obs;
    }
    ...
}

然后单篇文章组件视图如下所示:

<h1>{{ article.properties.short_descr }}</h1>
<ul>
    <li>{{ article.properties.resource.created_at }}</li>
    <li>{{ article.properties.resource.updated_at }}</li>
</ul>
<div>
    {{ article.properties.content }}
</div>

我认为我需要先获取id get参数,然后再执行加载文章数据的ajax调用。但是,我不确定如何做到这一点。使用Angular 4时,在组件之间管理此类异步依赖关系的最佳策略是什么?

1 个答案:

答案 0 :(得分:3)

您需要了解有关组件生命周期的更多信息。

输入,如articleId,永远不会在构造函数中可用:angular需要通过调用构造函数来构造组件,然后才能设置用@Input修饰的字段。

因此,如果您想知道输入的初始值,则需要在ngOnInit()生命周期钩子中执行此操作。

在这种情况下,如果父级中激活的路由的queryParams发生更改,那么articleId将获得一个新值。如果这是一种可能性(例如,父路由使用不同的查询参数链接到自身),则需要对输入中的更改做出反应。这可以使用ngOnChanges生命周期钩子来完成。

所有这些都在the documentation中描述。

您还需要了解依赖注入。您应该将其作为服务,并将其注入组件中,而不是在组件中创建ArticleOrm对象。这是使您的代码可测试(和惯用)的原因。