【问题标题】:Two-Way data binding in *ngFor*ngFor 中的双向数据绑定
【发布时间】:2016-06-04 00:43:13
【问题描述】:

我创建了一个用作开关的组件。您可以像使用复选框一样使用它。这是一个精简版。

my-switch.component.ts:

import {Component, Input, Output, EventEmitter} from '@angular/core';

@Component({
    selector: 'my-switch',
    template:    `<a (click)='toggle()'>
                    <span *ngIf='value'>{{onText}}</span>
                    <span *ngIf='!value'>{{offText}}</span>
                  </a>`
})
export class MySwitchComponent {
    @Input() onText: string = 'On';
    @Input() offText: string = 'Off';
    @Input() value: boolean;

    @Output() change = new EventEmitter <boolean> ();

    position: string;

    toggle() {
        this.value = !this.value;
        this.change.emit(this.value);
    }
}

我的计划是这样使用它:

父组件.ts

import {Component} from '@angular/core';
import {MySwitchComponent} from 'my-switch.component';

@Component({
    selector: 'my-sites',
    directives: [MySwitchComponent]
    template: `<table>
                 <tr *ngFor='let item of items'>
                   <td>
                     <my-switch 
                       [(value)]='item.options.option1'
                       (change)='logItem(item)'>
                     </my-switch>
                   </td>
                 </tr>
               </table>`
})
export class MySitesComponent {
    items: Object[] = [
        {options: { option1: false }}
    ];

    logItem(item) {
        console.log(item)
    }   
}

同样,这是简化的,但我认为说明了我的期望。我的期望是,当单击开关时,视图会从“关闭”更新为“打开”,并记录选项的值。问题是记录的值如下所示:

{options: {option1: false}}

我认为被迭代的项目是只读的。我知道我可以解决这个问题,但我想知道我正在尝试做的事情是否可行或不明智,以及为什么它不起作用。

【问题讨论】:

    标签: angular angular2-template


    【解决方案1】:

    Angular 将[(x)] 语法“脱糖”为用于属性绑定的x 输入属性和用于事件绑定的xChange 输出属性。 -- reference

    因此,如果您将输入属性命名为value,则必须将输出属性命名为valueChange:

    @Output() valueChange = new EventEmitter <boolean> ();
    

    这是您遗漏的唯一难题。您现在在父组件和子组件之间拥有双向数据绑定。

    如果要在子组件改变/emit()s 值时执行一些逻辑,在父组件中捕获(valueChange) 事件:

    (valueChange)='logItem(item)'>
    

    Plunker


    我也建议

    console.log(JSON.stringify(item))
    

    【讨论】:

      【解决方案2】:

      在父子场景中,您可以利用xxxChange Output property 的双向绑定,如下所示,
      在父子场景中 - [(xxx)]="someValue"
      在孩子 - @Input xxx: boolean;
      @Output() xxxChange = new EventEmitter &lt;boolean&gt; ();

      注意xxxChange 属性。在您的情况下缺少哪个

      现在,Look here for the code- Plunker

      <td> From Parent - {{item.options.option1}}   <--------------------value will keep changing
                           <my-switch 
                             [(value)]='item.options.option1'>  <---------two way binding
                           </my-switch>
       </td>
      

      请注意,[()] 表示两种方式绑定,因此在 parent 中您无需使用 (valueChange)="someValue=$event" 来捕捉更改。 [(value)]='item.options.option1' 会自动将新的或更改的值绑定到 item.options.option1。


      export class MySwitchComponent {
      
          @Input() value: boolean;
          @Output() valueChange = new EventEmitter <boolean> ();  <----xxxChange output property
      
      ...
      ...
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-28
        • 2017-11-07
        • 1970-01-01
        • 2016-12-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多