如何在另一个组件中获取指令/组件实例

How can I get a directive/component instance inside another component?

本文关键字:组件 取指令 实例 获取 另一个      更新时间:2023-09-26

我有一个AlertComponent,我想在我的AppComponent中使用它作为指令,并将其公开,以便它可以(作为一种单例)用于AppComponent中的所有路由/子组件。但是,我似乎找不到一种方法来将AlertComponent对象的实例用作指令,以便调用它的方法并查看对指令所做的更改(即,在页面中添加/删除警报)。

这是AlertComponent:

import { Component } from 'angular2/core';
import { Alert } from './model';
@Component({
    selector: 'alerts',
    templateUrl: './alert/index.html'
})
export class AlertComponent {
    alerts: Array<Alert>;
    constructor() {}
    add(alert: Alert) {
        this.alerts.push(alert);
    }
    remove(index: number) {
        this.alerts.splice(index, 1);
    }
    clear() {
        this.alerts = [];
    }
}
export { Alert };

和AppComponent:

import { Component, OnInit, provide } from 'angular2/core';
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/router';
import { HTTP_PROVIDERS, RequestOptions } from 'angular2/http';
import { CookieService } from 'angular2-cookie/core';
import { UserComponent } from '../user/component';
import { AlertComponent, Alert } from '../alert/component';
import { ExtendedRequestOptions } from '../extended/RequestOptions';
import { UtilObservable } from '../util/observable';
@Component({
    selector: 'app',
    template: `
<alerts></alerts>
<router-outlet></router-outlet>
`,
    //styleUrls: [ 'app/style.css' ],
    directives: [
        ROUTER_DIRECTIVES,
        AlertComponent
    ],
    providers: [
        ROUTER_PROVIDERS,
        HTTP_PROVIDERS,
        provide(RequestOptions, { useClass: ExtendedRequestOptions }),
        CookieService,
        UtilObservable,
        AlertComponent
    ]
})
@RouteConfig([{
    path: '/user/:action',
    name: 'User',
    component: UserComponent,
    useAsDefault: true
}
])
export class AppComponent implements OnInit {
    constructor(public _alert: AlertComponent) {}
    ngOnInit() {
        this._alert.add(new Alert('success', 'Success!'));
    }
}

我想让AlertComponent的相同实例可用于AppComponent的所有子代路由/子代(例如UserComponent),以便向同一指令添加警报。

这可能吗?或者还有其他更合适的方法吗?

[更新]

所选的解决方案回答了标题问题,但我也想有一个简单的解决方案来在我的组件之间共享警报。以下是如何做到这一点:

警报组件:

import { Component } from 'angular2/core';
import { Alert } from './model';
export class Alerts extends Array<Alert> {}
@Component({
    selector: 'alerts',
    templateUrl: './alert/index.html'
})
export class AlertComponent {
    constructor(public alerts: Alerts) {}
    add(alert: Alert) {
        this.alerts.push(alert);
    }
    remove(index: number) {
        this.alerts.splice(index, 1);
    }
    clear() {
        this.alerts.length = 0;
    }
}
export { Alert };

应用组件:

import { Component, provide } from 'angular2/core';
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/router';
import { HTTP_PROVIDERS, RequestOptions } from 'angular2/http';
import { AlertComponent, Alerts } from '../alert/component'
import { UserComponent } from '../user/component';
import { ExtendedRequestOptions } from '../helpers/extensions';
@Component({
    selector: 'app',
    template: `<router-outlet></router-outlet>`,
    directives: [
        ROUTER_DIRECTIVES
    ],
    viewProviders: [
        provide(Alerts, { useValue: [] })
    ],
    providers: [
        ROUTER_PROVIDERS,
        HTTP_PROVIDERS,
        provide(RequestOptions, { useClass: ExtendedRequestOptions })
    ]
})
@RouteConfig([{
    path: '/user/:action',
    name: 'User',
    component: UserComponent,
    useAsDefault: true
}
])
export class AppComponent {}

基本上,我提供了一个警报的单例数组,每个AlertComponent都使用它。

如果您想在指令之外使用provide(),可以将其移动到provider(而不是viewProviders),但如果不想,请保持简单并以这种方式限制它。

希望这能帮助到某人:)

您需要使用ViewChild装饰器来引用它:

@Component({
})
export class AppComponent implements OnInit {
  @ViewChild(AlertComponent)
  _alert: AlertComponent;
  ngAfterViewInit() {
    // Use _alert
    this._alert.add(new Alert('success', 'Success!'));
  }
}

在调用ngAfterViewInit钩子方法之前设置@ViewChild

将其公开,以便所有从AppComponent路由/子级组件。

或者还有其他更合适的方法吗?


AlertComponent创建并引导服务,如以下

警报服务

import {Injectable} from '@angular/core';
import {Subject} from 'rxjs/Subject';
import 'rxjs/add/operator/share';
@Injectable()
export class AlertService {
  private _alerts: Array<Alert> = [];
  public alertsChange: Subject<Array<Alert>> = new Subject();
  public get alerts(): Array<Alert> {
    return this._alerts;
  }
    add(alert: Alert) {
        this._alerts.push(alert);
        this.alertsChange.next(this._alerts);
    }
    remove(index: number) {
        this._alerts.splice(index, 1);
        this.alertsChange.next(this._alerts);
    }
    clear() {
        this._alerts = [];
        this.alertsChange.next(this._alerts);
    }
}

引导警报服务

import {bootstrap} from '@angular/platform-browser-dynamic';
import {YourApp} from 'path/to/YourApp-Component';
import { AlertService} from 'path/to/alert-service';
bootstrap(YourApp, [AlertService]);

警报组件

import { Component } from 'angular2/core';
import { Alert } from './model';
import { AlertService} from 'path/to/alert-service';
@Component({
    selector: 'alerts',
    templateUrl: './alert/index.html'
})
export class AlertComponent {
    alerts: Array<Alert>;
    constructor(alertService: AlertService) {
      alertService.alertsChange.subscribe((moreAlerts: Array<Alert>) => {
         this.alerts = moreAlerts;
      })
    }
}

所有路线/子组件

(示例):

import { Component} from '@angular/core';
import { AlertService} from 'path/to/alert-service';
@Component({
   template: `.....`
})
export class SampleComponent {
  constructor(public alerts: AlertService){} 
  ngOnInit(){
    this.alerts.add(new Alert('success', 'Success!'));
  }
  ngOnDestroy(){
    this.alerts.clear();
  }
}

要查看其他类似的示例,请参阅以下问题