如何访问在父组件上定义的ViewChild参考-Angular 2 [英] How to access ViewChild reference defined on parent component - Angular 2
问题描述
我在应用模板(根组件模板)中定义了一个spinner/loader元素,例如
<!--I have it here so that I don't have to paste it in all my templates-->
<div #spinner></div>
在我的子组件中,我尝试使用@ViewChild
访问它,但似乎总是返回undefined.我在子组件中访问此代码的代码是
@ViewChild('spinner', { read: ViewContainerRef }) container: ViewContainerRef; //this is always undefined
但是,当我将#spinner
放在子组件的HTML中时,它会被正确拾取.
是否可以将子组件中父组件中定义的元素作为ContainerRef
?
我需要视图引用来使用ComponentFactoryResolver
在其上动态创建组件.
似乎是类似问题,但找不到解决方法./p>
我现在正在使用可观察的共享服务,但仍然不会在.next
上引发事件.
这是我在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
};
}
在SpinnerService中,我有
@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);
}
}
在调用组件中,我有
@Component({
selector: 'edit-auction',
templateUrl: '/auctions/edit.html'
})
export class EditAuctionComponent {
constructor(public spinnerService: SpinnerService) { }
ngAfterViewInit() {
//start the spinner
this.spinnerService.showSpinner();
}
}
在app.module.ts(根模块)中
@NgModule({
imports: [BrowserModule, FormsModule, HttpModule, routes],
declarations: [..],
providers: [NotificationsService, SpinnerService],
bootstrap: [AppComponent]
})
export class AppModule { }
从其他组件访问数据对我来说听起来并不好.
对于您可能想做的最好的事情是定义将共享可观察的服务:
@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();
}
}
然后在您的根组件中订阅
eventServiceInstance.spinnerStatus.subscribe(state=>{
//thisSpinner.visible = state
})
现在您将在所有其他地方打电话
eventServiceInstance.showSpinner()
eventServiceInstance.hideSpinner()
PS.为了使其正常工作,应在NgModule中而不是组件内部添加EventService提供程序
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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!