Angular 8升级后无法访问嵌套对象

时间:2019-10-28 14:20:27

标签: angular typescript angular8

我有一个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中做事的正确方法?

2 个答案:

答案 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);
}

https://www.learnrxjs.io/subjects/