首页 文章

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

提问于
浏览
1

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

我在下面添加了一个完整的Plunker链接 .

该组件有两个属性( gridmessage ),两个属性都有setter和getter .

grid 属性基于"type"接口 IGridmessagestring . 当动态创建组件并将其添加到父组件时, gridmessage 都会添加到组件实例中 .

gridmessage 的setter调用一个名为 consolelog 的函数 .

根据各自输入的更改, gridmessage 的更改检测似乎正在起作用 .

我遇到的问题是在 message setter中正确调用 consolelog 函数,但 consolelog 函数未在 grid setter中正确调用 .

模板:

<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');
   }
 }

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

1 回答

  • 1

    根据你在评论中所说的,我还有两个关于你可能正在寻找的方法的猜测:

    • 是@ngrx / store方法 . (这是有据可查的)

    • 是在服务中将 grid 设为私有 Subject (或来自'rxjs'的BehaviorSubject),并使setter和getter服务 .

    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 . 但在这种情况下,您可以确定如果您在一个地方进行更改,则所有订阅者都将收到更改 .

相关问题