动态组件中的角度变化检测

时间:2018-09-13 04:10:14

标签: angular angular2-changedetection

我在Angular中动态添加的组件中的更改检测遇到问题。

我在下面添加了指向完整Plunker的链接。

该组件具有两个属性(网格消息),两个属性都有设置器和获取器。

网格属性基于“类型”界面 IGrid ,而消息字符串。 动态创建组件并将其添加到父组件时,网格消息都会添加到组件实例。

网格消息的设置者调用名为 consolelog 的函数。

根据各自输入的更改,网格消息的更改检测似乎都可以正常工作。

我遇到的问题是在消息设置器中正确调用了 consolelog 函数,但是没有在 consolelog 函数中在网格设置器中正确调用了。

模板:

<div>
  <div><b>grid.pinnedColumnHeaders</b></div> 
  input: 
  <input type="checkbox" 
    name="grid.pinnedColumnHeaders" 
    [(ngModel)]="grid.pinnedColumnHeaders">
</div>
<div>
  value: {{ grid.pinnedColumnHeaders || '[blank]' }}
</div>
<hr>
<div>
  <div><b>message:</b></div>
  input: <input type="text" name="message" 
  [(ngModel)]="message">
</div>
<div>
  value: {{ message || '[blank]' }}
</div>

组件:

@Component({
  selector: 'app-change-detection-onpush',
  template: `...`,
  changeDetection: ChangeDetectionStrategy.OnPush
})

export class ChangeDetectionOnPushComponent implements IPage {
    private _message: string;
    private _grid: IGrid;

    ngAfterViewInit() {

    }

    constructor(private cdRef: ChangeDetectorRef) { }

    set grid(val: string) {
      this.cdRef.markForCheck();
      this.logconsole();
      this._grid = val;
    }

    get grid() {
      return this._grid;
    }

    set message(val: string) {
      this.cdRef.markForCheck();
      this.logconsole();
      this._message = val;
    }

    get message() {
      return this._message;
    }

   logconsole(){
     console.log('test');
   }
 }    

完整柱塞: https://next.plnkr.co/edit/t1xK698tsJDnzS5E?open=lib%2Fapp.ts&deferRun=1

1 个答案:

答案 0 :(得分:1)

根据您在评论中所说,我对您可能要使用的方法还有两个猜测:

  1. 是@ ngrx / store方法。 (有据可查)
  2. 是将grid设为私有Subject(还是“ rxjs”的BehaviorSubject) 在您的服务中,并在服务中使设置者和获取者受益。

    import { Injectable } from '@angular/core';
    import { Subject } from 'rxjs';
    
    @Injectable()
      export class MyService{
    
        private grid: Subject<IGrid> = new Subject<IGrid>();
    
        getGrid(): Observable<IGrid> {
          return this.grid.asObservable();
        };
    
        setGrid(values: IGrid): void {
          this.grid.next(values);
        }
    
    }
    

    然后在您的任何组件中使用(请注意,不要忘记在ngOnDestroy()上设置unsubscribe

    export class MyComponent {
      grid: IGrid;
      constructor(private service: Myservice){}
    
      getGrid(): void {
        this.service.getGrid().subscribe((grid: IGrid) => this.grid = grid);
      }
    
      setGrid(gridData: IGrid): void {
        this.service.setGrid(gridData);
      }
    }
    

仍然,在这种方法中,您必须按照上面的建议处理输入更改,因为如果仅对象的一部分发生了更改,ngModel不会调用setter。但是在这种情况下,您可以确定,如果在一个地方进行更改,则所有订阅者都会收到更改。