我有一个Angular 2应用程序,并决定升级到Angular 8(以前没有使用2以上的版本)。
在一种情况下,我有一个带有动态加载的内部内容组件的对话框组件,但是该内容组件没有接收分配给它的变量。这些以前可以在ngOnInit
上访问,更不用说ngAfterViewInit
了,但是现在不能访问。
以下是最终(内容组件)对象的一些示例代码:
public params: ContentParams;
public isDataValid = true;
public error = '';
constructor() {
}
ngAfterViewInit() {
const o = this;
const t = setTimeout(function() {
console.log(o.params); // works
}, 500);
console.log(this.params); // undefined
}
这是父级(对话框组件)的创建+向内容组件的参数分配:
ngAfterViewInit(): void {
const factory = this._componentResolver.resolveComponentFactory(this.contentComponentType);
this._dialogContentComponent = this.contentContainerRef.createComponent(factory).instance as IDialogContentComponent<any, any>;
this._changeDetectorRef.detectChanges(); // necessary change for the dialog component to appear
if (this._dialogConfig.contentParams) {
this._dialogContentComponent.params = this._dialogConfig.contentParams;
}
}
我需要订阅的内容组件中是否存在其他生命周期事件?还是这不是在新版本的Angular中做事的正确方法?
答案 0 :(得分:2)
对于这种情况,我更喜欢使用主题
在一项共享服务中添加主题,然后在组件或服务之间共享状态。
@Injectable()
export class SharedService {
public params$: Subject<any> = new Subject();
constructor() { }
}
constructor(private _sharedService: SharedService) {
this._sharedService.params$.next({test: 1})
}
import { Component, OnInit, AfterViewInit } from '@angular/core';
import { Subject } from 'rxjs';
import { SharedService } from './shared.service';
interface ContentParams {}
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
public params: ContentParams;
public isDataValid = true;
public error = '';
constructor(private _sharedService: SharedService) {
}
ngOnInit() {
this._sharedService.params$.subscribe( params => {
console.log(params) // {test: 1}
this.params = params;
});
}
}
答案 1 :(得分:1)
此链接完成执行后,您的 AfterViewInit()将触发,因此在调用该链接时尚未加载 params 。这就是 setTimeout()起作用的原因。
this._dialogContentComponent = this.contentContainerRef.createComponent(factory).instance as IDialogContentComponent<any, any>;
您可以利用RxJS的强大功能来提供帮助(不要忘记取消订阅的部分):
import { Subject } from 'rxjs';
export class Something {
public params: ContentParams;
public isDataValid = true;
public error = '';
public params$ = new Subject();
constructor() {
this.params$.subscribe((value) => {
this.params = value;
});
}
ngAfterViewInit() {
const o = this;
const t = setTimeout(() => {
console.log(this.params); // works
}, 500);
console.log(this.params); // undefined
}
ngOnDestroy() {
this.params$.unsubscribe();
}
}
然后发出一个新值,而不是直接分配:
if (this._dialogConfig.contentParams) {
this._dialogContentComponent.params$.next(this._dialogConfig.contentParams);
}