如何在另一个组件中获取指令/组件实例?
Posted
技术标签:
【中文标题】如何在另一个组件中获取指令/组件实例?【英文标题】:How can I get a directive/component instance inside another component? 【发布时间】:2016-09-05 08:33:28 【问题描述】:我有一个 AlertComponent,我想将它用作我的 AppComponent 中的指令并将其公开,以便它可用于(作为一种单例)来自 AppComponent 的所有路由/子组件。但我似乎无法找到一种方法来获取用作指令的 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!'));
我希望 AppComponent 的所有后代路由/子级(例如 UserComponent)都可以使用相同的 AlertComponent 实例,以便将警报添加到同一指令。
这可能吗?还是有其他更合适的方法来做到这一点?
[更新]
选择的解决方案回答了标题问题,但我也希望有一个简单的解决方案来在我的组件之间共享警报。这样做的方法如下:
警报组件:
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() 移动到提供程序(而不是 viewProviders),但如果不是,请保持简单并以这种方式限制它。
希望这可以帮助某人:)
【问题讨论】:
【参考方案1】:公开它,以便它(作为一种单例)可供所有 来自 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();
查看其他类似示例see this question
【讨论】:
这肯定行得通。谢谢!不过,蒂埃里·坦普利尔首先解决了标题问题,所以我会公平地把这个问题交给他。我认为像我这样的新人应该先看到他的答案,然后再实施更复杂的东西;例如,我选择适应蒂埃里的更简单的例子。当然也给你竖起大拇指。再次感谢! 不客气....你做了正确的事.... 【参考方案2】:你需要使用ViewChild
装饰器来引用它:
@Component(
)
export class AppComponent implements OnInit
@ViewChild(AlertComponent)
_alert: AlertComponent;
ngAfterViewInit()
// Use _alert
this._alert.add(new Alert('success', 'Success!'));
@ViewChild
是在调用ngAfterViewInit
钩子方法之前设置的。
【讨论】:
感谢您的回答!有什么方法可以在两个或多个组件之间共享相同的 ViewChild/Directive 数据? 我不这么认为。在这种情况下,您需要利用可观察的共享服务。这样您就可以通知并被通知。有关详细信息,请参阅此链接:angular.io/docs/ts/latest/cookbook/…以上是关于如何在另一个组件中获取指令/组件实例?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 React Hooks 在另一个组件中获取表单的输入值