【问题标题】:Inject the instance of a component in a service在服务中注入组件的实例
【发布时间】:2017-04-16 05:04:26
【问题描述】:

出于任何好的原因,我正在尝试将我的组件注入到服务中,但我获得了它的一个新实例。我用这段代码重现了我的问题:

该组件将在h1中显示实例号:

@Component({
    selector: 'my-component',
    template: '<h1>Instance number {{count}}</h1>'
})
export class MyComponent {
    private static i = 0;               /* <-- counts the myComponent's instances here */
    private _count: number = i++;
    get count(): number {return this._count}
}

Service会在控制台中记录实例号:

@Injectable()
export class MyService {
    constructor(myComponent: MyComponent) {
        console.log("Instance number " + myComponent.count);
    }
}

主组件会将组件注入视图和服务中:

@Component({
    selector: 'app-root',
    template: '<my-component></my-component>',
})
export class AppComponent {
    constructor(service: MyService) {
    }
}

我正在使用 angular-cli,我的 app.module.ts 看起来:

@NgModule({
  declarations: [
    AppComponent,
    MyComponent
  ],
  imports: [
    BrowserModule,
  ],
  providers: [MyComponent, MyService],
  bootstrap: [AppComponent]
})
export class AppModule { }

目前,我的控制台显示Instance number 0,我的html 显示Instance number 1。 如何获取相同的实例?

感谢阅读

【问题讨论】:

    标签: angular inject


    【解决方案1】:

    这不起作用。如果您的应用程序有该组件的多个实例,应该注入哪个实例。

    您可以做的例如是将服务注入到组件中,并使组件将自身传递给服务

    @Component({
        selector: 'my-component',
        template: '<h1>Instance number {{count}}</h1>'
    })
    export class MyComponent {
    
        constructor(service: MyService) {
          service.myComponent = this;
        }
    
        private static i = 0;
        private _count: number = i++;
        get count(): number {return this._count}
    }
    

    最好不要将组件传递给服务,而是使用可观察对象来通知组件有关事件并让组件完成其余的工作。

    更多详情见https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

    【讨论】:

    • 为什么更好?当您将组件传递给服务时,至少几个月后您仍然了解您的代码在做什么。
    • @QianChen 在 Angular 中,理念是您操纵状态,而视图(Angular 组件)只需渲染该状态以仅在一个方向上保持干净的依赖关系。如果您以这种方式传递组件,您就会使组件成为状态的一部分。从长远来看,这将导致混乱。如果你不遵循这个 Angular 哲学,那么将组件传递给服务不会有太大的不同。
    • 我明白你说的。在实践中,我发现 observables 会造成混乱。
    【解决方案2】:

    感谢您的回答@Günter。我在这里为任何感兴趣的人发布我的新组件和服务订阅:

    可观察服务:

    @Injectable()
    export class MyService implements OnDestroy {
        private _count:number = 0;
        public numberSource = new Subject<number>();
        private numberObservable: Observable<number> = this.numberSource.asObservable().share();
    
        public count() {this.numberSource.next(this._count++);}
        public subscribe(s: any) {return this.numberObservable.subscribe(s);}
        public ngOnDestroy() {this.numberSource.complete();}
    }
    

    一个订阅者组件(我可以有很多):

    @Component({
        selector: 'my-component',
        template: `
    <button (click)="increment()" >Count !</button>
    <div *ngFor="let n of numbers">{{n}}</div>
    `
    })
    export class MyComponent {
        private numbers: number[] = [];
        constructor(private myService: MyService) {
            myService.subscribe((n:number) => this.numbers.push(n));
        }
        increment() {
            this.myService.count();
        }
    }
    

    我不知道我是否清楚,但这正是我想要的。谢谢!

    【讨论】:

    • 你得到答案了吗?
    猜你喜欢
    • 2018-07-05
    • 2016-08-08
    • 2017-07-23
    • 1970-01-01
    • 2021-10-04
    • 1970-01-01
    • 2016-09-07
    • 2020-06-25
    • 1970-01-01
    相关资源
    最近更新 更多