Angular公共组件开发II

1,452 阅读2分钟

小谈:

上一篇:Angular公共组件开发谈了Angular公共组件的开发,其中有个细节不知道大家注意到没有。

不知道大家有没有考虑过这边为什么在Angular的Onchange()生命周期里初始化数据。其实,这是因为通过@Input拿到的数据对于这个公共组件来说是异步的,所以,在构造器里拿不到这个数据,在OnInit里也拿不到。只有在第二次调用Onchanges()才能获得dataSource。

异步传输数据

异步传输的方法在Angular里很常见,

async ngOnInit():Promise<void> {
    
    do something...
    await this.another();
    //another执行完后开始执行
    this.then();
}

下面我们就谈谈三种传播异步数据到组件的方式。

第一种

使用 *ngIf

比如上图, 可以在mat-table外层包一对div,使用*ngIf="renderedDataSource"去根据值判断是否渲染表格,只有取到值时才去渲染表格,就避免了异步的问题。在TS里就不用在OnChanges()生命周期里初始化dataSource的值了,直接在OnInit()里调用即可。另外一点,使用这种方法在定义dataSource时应当先给它赋上空值 dataSource = [];

第二种

就是上面用的 ngOnchanges()方法。

第三种

利用RxJs BehaviorSubject 不了解这个方法的戳这里.
只要是先 new 一个 BehaviorSubject,

 private _data = new BehaviorSubject<any[]>([]);

然后用get()和set()方法监测变化值.

// initialize a private variable _data, it's a BehaviorSubject
   private _data = new BehaviorSubject<Post[]>([]);

   // change data to use getter and setter
   @Input()
   set data(value) {
       // set the latest value for _data BehaviorSubject
       this._data.next(value);
   };

   get data() {
       // get the latest value from _data BehaviorSubject
       return this._data.getValue();
   }

之后在OnInit()里处理就行了

  ngOnInit() {
       // now we can subscribe to it, whenever input changes, 
       this._data
           .subscribe(x => {
           this.dataSource = x;
           });
   }

如果想取一次值之后就解除订阅,可以用

 ngOnInit() {
       this._data
           // add this line
           // listen to data as long as groupPosts is undefined or null
           // Unsubscribe once groupPosts has value
           .takeWle(() =>!this.dataSourceSubscription)
           .subscribe(x => {
           this.dataSourceSubscription=this.xxx();
           });
   }
.takeWhile(() => !this.dataSourceSubscription)

这个方法是订阅之后立马取消订阅。
就说这么多吧,欢迎大家指正。