Angular 2组件视图 - 部分同步

时间:2017-05-25 18:13:44

标签: angular angular-material angular2-forms

我遇到了一个问题,即没有md前缀的HTML元素(例如<input mdInput>)与其基础模型保持同步,但那些是<md-select>和{{}} {1}} 更新,因此与基础模型不同步。

注意 - 我无法在此this Plunker中重新创建问题 - 但是,我的代码非常类似于我在本地运行的代码。我不知道如何进一步调查,所以我在这里尝试任何想法。

TL,DR - 我了解组件视图可能与其基础模型不同步,但会导致某些 UI元素(<md-checkbox>)保持同步而其他人不同步(<input><md-checkbox>)?  只有在事件(<md-select>mouseoverhover等)触发变更检测时才会同步后者?

详细信息 - 一个线索可能是在md-checkbox上使用click导致复选框变得不同步:

[(ngModel)]

但是,更改此项以绑定到该值,确保复选框保持同步(请参阅以下内容中添加<!-- Checkbox wasn't updated in UI until change detection triggered. --> <md-checkbox [(ngModel)]="node.checked" name="checked"></md-checkbox>

checked="{{node.checked}}"

所以我假设类似的问题正在影响<!-- This always remains in-sync. --> <md-checkbox [(ngModel)]="node.checked" name="checked" checked="{{node.checked}}"> ,只是我无法直接绑定到该值,因此它仍然不同步。

有关显示JSON“树”的递归呈现组件的示例,请参阅this Plunker。每个JSON对象(即节点)由四个字段组成:

  1. <md-select>
  2. title:string
  3. checked:boolean
  4. types:[]
  5. children:[]titlechecked字段只是虚拟值,但故意选择代表不同的材料设计表单字段:

    1. types - 简单。
    2. <input mdInput> - 复杂。
    3. <md-checkbox> - 复杂。
    4. <md-select>字段是“树”的形成方式。叶节点不会有children,但父节点将

      Leaf节点:children

      非叶​​节点:

      {'title': 'L1-A', 'checked': false, 'types': ['NUMBER']}

      我已经硬编码了两个代表起始状态和更新状态的JSON对象:

      {
        'title': 'L1-A',
        'checked': false,
        'types': ['NUMBER'],
        'children': [
          'title': 'L2-A',
          'checked': false,
          'types': ['NUMBER'],
        ]
      }
      

      您可能会看到JSON树结构相同但标题不同。 export class Tree { treeStart:any = { 'title' : 'L0', 'checked': false, 'types': ['NUMBER'] 'children' : [ {'title': 'L1-A', 'checked': false, 'types': ['STRING'] 'children' : [ {'title': 'L2-A','checked': false,'types': ['INTEGER']} ] } ] }; treeUpdated:any = { 'title' : 'L0-UPDATED', 'checked': true, 'types': ['NUMBER'] 'children' : [ {'title': 'L1-A-UPDATED', 'checked': true, 'types': ['NUMBER'] 'children' : [ {'title': 'L2-A-UPDATED','checked': true,'types': ['NUMBER']} ] } ] }; tree:any; constructor(private cdRef: ChangeDetectorRef) { this.tree = this.treeStart; } } 开始checked:false进行更新。 checked:true是根节点。

      两个Angular 2组件呈现JSON:

      • L0
      • tree-component.ts / tree-component.html

      node-component.ts / node-component.html通过渲染单个tree来解决问题。 node然后以递归方式为任何node呈现自己。

      使用children呈现的根节点(树):

      tree-component.html

      <md-card> <app-node [node]="tree"></app-node> </md-card> 递归渲染:

      node-component.html

      更新和重置按钮被添加到tree-component.html,因为更新和重置适用于树级别。

      <!-- Checked -->
      <md-checkbox [(ngModel)]="node.checked" name="checked"></md-checkbox>
      
      <!-- Title -->
      <md-input-container>
        <input mdInput placeholder="Title"
        #name="ngModel" [(ngModel)]="node.title"
        name="title" value="{{node?.title}}">
      </md-input-container>
      
      <!-- Types -->
      <md-select placeholder="Type" multiple="true"  color="accent [(ngModel)]="node.types">
      <md-option *ngFor="let type of allTypes" [value]="type.value {{type.display}}</md-option>
      </md-select>
      
      <!-- Recursive rendering -->
      <md-card *ngFor="let child of node?.children">
        <app-node *ngIf="child" [node]="child"></app-node>
      </md-card>
      

      单击Plunker example中的<button md-raised-button (click)="update()">Update</button> <button md-raised-button (click)="reset()">Reset</button> 按钮,在任意超时(模拟API调用)后加载更新的树:

      update

      呈现的JSON数量可能会非常大,后续树可能会非常深和/或很宽。因此,节点组件使用change push detection strategy

      update(): void {
        setTimeout(() => {
          this.apiCallback();
        }, 2000);
      }
      
      apiCallback(): void {
        this.tree = this.treeUpdated;
        this.cdRef.detectChanges();
      }
      

      树组件使用默认更改检测。

      我遇到的问题是@Component({ selector: 'app-node', templateUrl: './src/node.component.html', changeDetection: ChangeDetectionStrategy.OnPush }) export class Node implements OnInit { /* Node implementation goes here. */ } 这样的'简单'材料设计表单字段始终与模型保持同步,但mdInput等“复杂”表单字段在更新之前不会更新事件发生。

0 个答案:

没有答案