Angular 2选择与ngModel和@Input冲突

时间:2017-05-12 22:29:05

标签: angular

我在传播@Input和从角度材质中选择时遇到问题。我的选择取决于父级,并通过@Input和@Ouput进行通信。当我选择一个选项时,我会将值发送给父母,父母会拦截此回复并验证他是否可以更改该值。

如果父母告诉孩子由于某种原因无法更新其值,我不会更改子项输入中的值。在这种情况下,选择框中的ngModel不会反映Input的值。

我需要一种方法告诉我的孩子回到输入

中已经存在的初始值

显示孩子如何与父母沟通的示例:

@Component({
    selector: 'child',
    template: `
        <md-select placeholder="Périodes" name="Périodes"
            [ngModel]="selected" (ngModelChange)="filterOptionsChange($event, 'periode')">
            <md-option *ngFor="let periode of periodes" [value]="periode">
                Semaine {{periode.id}}
            </md-option>
        </md-select>`
})
export class Child {

    @Input() selected: any;
    @Output() filterChange = new EventEmitter<any>();

    filterOptionsChange(evt, type: string) {
        this.filterResult[type] = evt;
        this.filterChange.emit(this.currentFilter);
    }
}

@Component({
    selector: 'my-parent',
    template: `
        <div>
            <child [selected]="selected" (valueChanged)="validate($event)"></child>
        </div>`
})
export class App {
    selected:any;

    constructor() {
    }

    validate(event) {
        if (true) {
            // do that and change the selected value
        } else {
            //do nothing, and keep the initial selected value
        }
    }
}

1 个答案:

答案 0 :(得分:2)

您需要控制父组件中的选定值,并且所有值的对象引用应始终更改,即使我们需要保留以前的值。

https://plnkr.co/edit/YrTTScdjOnFvwUYO1OWR?p=preview

@Component({
    selector: 'child',
    template: 
    `
  <select #el (ngModelChange)="valueChanged.emit($event)" [ngModel]="selected"  [compareWith]="compareFn">
    <option *ngFor="let op of options"  [ngValue]="op">
       {{op.name}}
    </option>
  </select>
  {{selected.name}}
    `
  })
  export class Child {
    compareFn:
        (o1: any, o2: any) => boolean = (o1: any, o2: any) => o1 && o2? o1.id === o2.id: o1 === o2;
    @Input() selected: Object;
    @Output() valueChanged = new EventEmitter<any>();

    options = [
      {id:"1", name:'A'},
      {id:"2", name: 'B'},
      {id:"3", name:' C: Do not allow'},
      {id:"4", name:' D'}
    ];
  }

  @Component({
    selector: 'my-app',
    template: `
      <div>
        <child [selected]="selected" (valueChanged)="valueChanged($event)"></child>
      </div>
    `,
  })
  export class App {
    selected = {id:"1", name: 'A'};

    constructor() {
    }

    valueChanged(value) {
     // keep the previous for 3
     if(value.id === '3') {
       this.selected= Object.assign({}, this.selected);
     }
     else {
        // for all other values take that user selected
        this.selected= Object.assign({}, value);
     }
    }
  }