如何访问在父组件上定义的ViewChild引用 - Angular 2

Ali*_*aig 5 angular2-template angular

我在app模板(根组件的模板)中定义了一个spinner/loader元素

<!--I have it here so that I don't have to paste it in all my templates-->
<div #spinner></div>
Run Code Online (Sandbox Code Playgroud)

在我的子组件中,我试图使用它来访问它,@ViewChild但似乎总是返回undefined.我在子组件中访问它的代码是

@ViewChild('spinner', { read: ViewContainerRef }) container: ViewContainerRef;  //this is always undefined
Run Code Online (Sandbox Code Playgroud)

但是,当我将我#spinner的子组件的HTML 放入其中时,它会被正确地拾取.

有没有办法将子组件中父组件中定义的元素作为一个ContainerRef

我需要视图引用来动态地使用它创建组件ComponentFactoryResolver.

这似乎是一个类似的问题,但无法找到克服的方法.

编辑:我现在使用与observable的共享服务,但它仍然没有引发事件.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
    };
}
Run Code Online (Sandbox Code Playgroud)

在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);
    }
}
Run Code Online (Sandbox Code Playgroud)

在调用组件中,我有

@Component({
    selector: 'edit-auction',
    templateUrl: '/auctions/edit.html'
})
export class EditAuctionComponent {

    constructor(public spinnerService: SpinnerService) {  }

    ngAfterViewInit() {
        //start the spinner
        this.spinnerService.showSpinner();
    }
}
Run Code Online (Sandbox Code Playgroud)

在app.module.ts(根模块)

@NgModule({
    imports: [BrowserModule, FormsModule, HttpModule, routes],
    declarations: [..],
    providers: [NotificationsService, SpinnerService],
    bootstrap: [AppComponent]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)

Vol*_*hat 7

从其他组件访问数据对我来说听起来不太好.

对于您要做的事情,最好的方法是定义将共享可观察的服务:

@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();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在您的根组件中,您将订阅

eventServiceInstance.spinnerStatus.subscribe(state=>{
            //thisSpinner.visible = state
        })
Run Code Online (Sandbox Code Playgroud)

而现在在其他所有地方你都会打电话

eventServiceInstance.showSpinner()
eventServiceInstance.hideSpinner()
Run Code Online (Sandbox Code Playgroud)

PS.为了使其工作,应在NgModule中添加EventService提供程序,而不是在组件内部