本文介绍了如何访问父组件上定义的 ViewChild 引用 - Angular 2的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我在应用程序模板(根组件的模板)中定义了一个微调器/加载器元素,例如
<!--我把它放在这里,这样我就不必将它粘贴到我所有的模板中--><div #spinner></div>
在我的子组件中,我尝试使用 @ViewChild
访问它,但这似乎总是返回 undefined.我在子组件中访问它的代码是
@ViewChild('spinner', { read: ViewContainerRef }) 容器:ViewContainerRef;//这总是未定义的
但是,当我将 #spinner
放在子组件的 HTML 中时,它会被正确拾取.
有没有办法将子组件中父组件中定义的元素作为 ContainerRef
获取?
我需要视图引用以使用 ComponentFactoryResolver
在其上动态创建组件.
这似乎是一个类似的问题,但找不到克服的方法.
我现在使用可观察的共享服务,但它仍然没有在 .next
上引发事件.
这是我在 SpinnerComponent
中的代码@Component({选择器:'微调器',styleUrls: ['app/styles/spinner.component.css'],模板:`<div [hidden]="state.visible" class="in modal-backdrop spinner-overlay"></div><div class="spinner-message-container" aria-live="assertive" aria-atomic="true"><div class="spinner-message" [ngClass]="spinnerMessageClass">{{ state.message }}</div>
`})导出类 SpinnerComponent {构造函数(微调服务:微调服务){spinnerService.spinnerStatus.subscribe(event => {console.log('事件:' + 事件);<= 没有被调用this.state.visible = 事件;});}公共状态 = {message: '请稍候...',可见:假};}
在 SpinnerService 中,我有
@Injectable()导出类 SpinnerService {公共事件:BehaviorSubject= new BehaviorSubject(false);public get spinnerStatus(): Observable{返回 this.events.asObservable();}公共 showSpinner() {this.events.next(true);}公共隐藏旋转器(){this.events.next(false);}}
在调用组件中,我有
@Component({选择器:'编辑拍卖',templateUrl: '/auctions/edit.html'})导出类 EditAuctionComponent {构造函数(公共微调服务:SpinnerService){}ngAfterViewInit() {//启动微调器this.spinnerService.showSpinner();}}
在 app.module.ts(根模块)中
@NgModule({进口:[BrowserModule,FormsModule,HttpModule,路线],声明:[..],提供者:[NotificationsService,SpinnerService],引导程序:[AppComponent]})导出类 AppModule { }
解决方案
从其他组件访问数据对我来说听起来不太好.
对于您尝试做的最好的事情可能是定义将共享可观察的服务:
@Injectable()导出类 EventService {public selectedCategoryName: string = '';私人事件 = 新的 BehaviorSubject(false);构造函数(){}公共 showSpinner(){this.events.next(真)}公共隐藏旋转器(){this.events.next(false);}public get spinnerStatus() : Observable{返回 this.events.asObservable();}}
然后在你的根组件中订阅
eventServiceInstance.spinnerStatus.subscribe(state=>{//thisSpinner.visible = state})
现在你会在所有其他地方打电话
eventServiceInstance.showSpinner()eventServiceInstance.hideSpinner()
附注.为了使其工作,EventService 提供者应该添加到 NgModule 中,而不是在组件内部
I have a spinner/loader element defined in app template (root component's template) like
<!--I have it here so that I don't have to paste it in all my templates-->
<div #spinner></div>
In my child components, I am trying to access it using @ViewChild
but that seems to always return undefined. My code for accessing this in child component is
@ViewChild('spinner', { read: ViewContainerRef }) container: ViewContainerRef; //this is always undefined
However when I place my #spinner
in my child component's HTML, it gets picked up correctly.
Is there a way to get the element defined in parent component in your child component as a ContainerRef
?
I need the view reference to create the component on it dynamically using ComponentFactoryResolver
.
It seems a similar issue but can't find a way to overcome.
EDIT: I am now using a shared service with the observable, but still it doesn't raise an event on .next
.
Here is my code in SpinnerComponent
@Component({
selector: 'spinner',
styleUrls: ['app/styles/spinner.component.css'],
template:
`<div [hidden]="state.visible" class="in modal-backdrop spinner-overlay"></div>
<div class="spinner-message-container" aria-live="assertive" aria-atomic="true">
<div class="spinner-message" [ngClass]="spinnerMessageClass">{{ state.message }}</div>
</div>`
})
export class SpinnerComponent {
constructor(spinnerService: SpinnerService) {
spinnerService.spinnerStatus.subscribe(event => {
console.log('Event: ' + event); <= not getting called
this.state.visible = event;
});
}
public state = {
message: 'Please wait...',
visible: false
};
}
In SpinnerService, I have
@Injectable()
export class SpinnerService {
public events: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
public get spinnerStatus(): Observable<boolean> {
return this.events.asObservable();
}
public showSpinner() {
this.events.next(true);
}
public hideSpinner() {
this.events.next(false);
}
}
And in the calling component, I have
@Component({
selector: 'edit-auction',
templateUrl: '/auctions/edit.html'
})
export class EditAuctionComponent {
constructor(public spinnerService: SpinnerService) { }
ngAfterViewInit() {
//start the spinner
this.spinnerService.showSpinner();
}
}
In app.module.ts (root module)
@NgModule({
imports: [BrowserModule, FormsModule, HttpModule, routes],
declarations: [..],
providers: [NotificationsService, SpinnerService],
bootstrap: [AppComponent]
})
export class AppModule { }
解决方案
Accessing data from other components does not sounds good to me.
For what you are trying to do probably best would be to define service which will share observable:
@Injectable()
export class EventService {
public selectedCategoryName: string = '';
private events = new BehaviorSubject<Boolean>(false);
constructor() {
}
public showSpinner(){
this.events.next(true)
}
public hideSpinner(){
this.events.next(false);
}
public get spinnerStatus() : Observable<boolean> {
return this.events.asObservable();
}
}
Then in your root component you will subscribe to
eventServiceInstance.spinnerStatus.subscribe(state=>{
//thisSpinner.visible = state
})
And now in all other places you will call
eventServiceInstance.showSpinner()
eventServiceInstance.hideSpinner()
PS. To make it works EventService provider should be added in NgModule and not inside of components
这篇关于如何访问父组件上定义的 ViewChild 引用 - Angular 2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!