Angular 8 / PrimeNg p复选框在选中时未更新UI

时间:2019-08-18 17:14:37

标签: angular primeng

我有以下代码:

update-season.component.html:

<div class="update-season-container">
    <div class="entry-row" *ngFor="let d of data">
        <app-multi-type-row
            [emailAddress]="emailAddress"
            [accessToken]="accessToken"
            [data]="d">
    </app-multi-type-row>
</div>

update-season.component.ts(不包含其他功能代码):

initialize = () => {
    this.adminService.getSeasonData(this.emailAddress, this.accessToken).subscribe(response => {
    const data = response.data;
    data.sort(this.compareSeasonEntries);
    this.data = data;
    this.appRef.tick();
    this.multiValueChildren.forEach(c => {
      c.setChecks();
    });
    this.appRef.tick();
  }, error => {
    // something
  });
}

multi-value-row.component.html:

<div class="multi-type-row-container">
<div class="row">
    <div class="mtr-group name">
        <div class="mtr-header">
            Field Name:
        </div>
        <div class="mtr-body">
            <input type="text" [(ngModel)]="data.name" />
        </div>
    </div>
    <div class="mtr-group">
        <div class="mtr-header">
            Environment:
        </div>
        <div class="mtr-body">

        </div>
    </div>
</div>
<div class="row">
    <div class="mtr-group check">
        <div class="mtr-header">
            Enable:
        </div>
        <div class="mtr-body">
            <p-checkbox binary="true" label="foo" (onChange)="doStuff()" [(ngModel)]="enableString"></p-checkbox>
        </div>
    </div>
    <div class="mtr-group value">
        <div class="mtr-header">
            String value:
        </div>
        <div class="mtr-body">
            <input type="text" [(ngModel)]="data.stringVal" />
        </div>
    </div>
</div>
<div class="row">
    <div class="mtr-group check">
        <div class="mtr-header">
            Enable:
        </div>
        <div class="mtr-body">
            <p-checkbox [(ngModel)]="enableInt" binary="true"></p-checkbox>
        </div>
    </div>
    <div class="mtr-group value">
        <div class="mtr-header">
            Integer value:
        </div>
        <div class="mtr-body">
            <input type="text" [(ngModel)]="data.intVal" />
        </div>
    </div>
</div>
<div class="row">
    <div class="mtr-group check">
        <div class="mtr-header">
            Enable:
        </div>
        <div class="mtr-body">
            <p-checkbox [(ngModel)]="enableBoolean" binary="true"></p-checkbox>
        </div>
    </div>
    <div class="mtr-group value">
        <div class="mtr-header">
            Boolean value:
        </div>
        <div class="mtr-body">
            <input type="text" [(ngModel)]="data.booleanVal" />
        </div>
    </div>
</div>

mult-value-row.component.ts:

@Input() data: MultiValueType = null;
@Input() emailAddress: string = null;
@Input() accessToken: string = null;

enableString = false;
enableInt = false;
enableBoolean = false;

constructor(private appRef: ApplicationRef) { }

ngOnInit() {
}

doStuff = () => {
  console.log(this.enableString);
  this.appRef.tick();
}

setChecks = () => {
  this.enableBoolean = this.data.booleanVal !== null;
  this.enableInt = this.data.intVal !== null;
  this.enableString = this.data.stringVal !== null;
  this.appRef.tick();
}

页面加载后,我将看到11个app-multi-value-row组件(来自ngFor)。页面加载后会发生以下情况:

1)我点击第一个enable string复选框

2)false被打印到控制台窗口(由于其初始状态为false,所以应该为true)。同时,所有其他10个多值行enable string复选框的UI都会更新以显示选中标记,只有第一个保持未选中状态。

3)再次单击同一复选框,UI将显示其选中状态,并且控制台窗口将显示true

4)取消选中/重新选中另一个组件的enable string复选框,该复选框会正常切换,并在控制台中打印正确的状态。

我尝试将setChecks代码放入ngChanges方法中,但是当调用appRef.tick()时,我得到了ApplicationRef.tick is called recursively,这很有意义,因为另一个代码已经在进行中零件。我想在所有组件都更新后更新UI更新。我只是似乎无法弄清为什么它的行为方式如此。

顺便说一句,更新季节组件位于ngIf的后面,我注意到如果将p复选框放在所有ngIf的前面,则它的运行情况正常。不知道为什么会这样,但想我会分享。

0 个答案:

没有答案