【发布时间】:2017-07-19 19:30:26
【问题描述】:
我有一个组件用于向我的应用程序显示一些常见的输出。该组件被注入到其他服务中,以便这些服务可以触发该行为。经过大量故障排除后,我想我已经将问题跟踪到 Angular 的 DI 创建组件的多个实例。我创建了一个简单的版本来说明这个问题。这是 Angular 2.4.x
应用模块:
import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {HttpModule} from '@angular/http';
import {AppComponent} from './app.component';
import {TestComponent} from "./test.component";
@NgModule({
declarations: [
AppComponent,
TestComponent
],
imports: [BrowserModule, FormsModule, HttpModule],
providers: [TestComponent],
bootstrap: [AppComponent]
})
export class AppModule {
}
测试组件(这是我试图用来显示信息并将其用作服务的组件的简化版本):
import {Component, OnInit} from '@angular/core';
@Component({
selector: 'app-test',
template: `<p>Message:</p>
<p *ngIf="show">hi</p>`
})
export class TestComponent {
private show: boolean = false;
doTest() {
setTimeout(() => {
console.log('timeout callback');
this.show = true;
}, 5000);
}
}
App 组件(使用我的测试组件的组件):
import {Component, OnInit} from '@angular/core';
import {TestComponent} from "./test.component";
@Component({
selector: 'app-root',
template:`
<h1>{{title}}</h1>
<app-test></app-test>
`
})
export class AppComponent implements OnInit{
title = 'app works!';
constructor(private test: TestComponent) { }
ngOnInit() {
this.test.doTest();
}
}
我希望的行为是 AppComponent 会调用 TestComponent 的 doTest 函数,并且 TestComponent 会在 5 秒后显示“hi”消息。
回调发生,我看到控制台消息,但没有显示“hi”。我认为依赖注入提供了单独的实例,因此注入 App 的构造函数的实例与 App 模板中的实例不同。
如果我的理解是正确的,我该如何让它在两种情况下都是相同的?我是否错过了实现这种行为的更好方法?
【问题讨论】:
-
要获得对测试组件的引用,您可以在
AppComponent的模板中使用<app-test #test>或使用ViewChild装饰器。将其注入构造函数是不正确的,但考虑这样做是合理的。 -
TestComponent或任何其他组件不应在provider属性中声明为提供程序。通常,您只会放置用@Injectable() 修饰的类,通常是服务。 -
我本来打算有一个单独的服务,但我在某处(我认为是另一个堆栈溢出帖子)读到 Component 扩展了 Injectable,因此任何标记为组件的东西都可以被视为可注入的(无论是否这是明智的做法...)
-
@AlexanderStaroselsky 您绝对正确,不应将组件添加到
providers数组中,但它与Injectable装饰器工厂无关。 -
@AluanHaddad 你是绝对正确的。我同意您利用
ViewChild解决此问题的方法。我发表评论的目的是促进关于providers的更好实践。谢谢!
标签: angular