NgModel订阅仅在angular2

时间:2016-02-07 04:54:28

标签: typescript angular

我在下面有这个代码。基本上它是一个带有指令的组件,它可以订阅textarea的模型。

如果我键入textarea,则订阅触发器和控制台日志会发生更改,但是如果模型在外部更改并从组件中的@Input接收,则textarea中的订阅不会触发,即使文本在textarea正在更新。

为什么文本发生变化时不会触发?

  @Directive({
      selector: 'textarea[mydir]',
      host: {'ngFormControl':'myCtrl'}
  })
  class MyDirective {
    myCtrl: any;
    constructor(){
            this.myCtrl = new Control();
            this.myCtrl.valueChanges.subscribe(
            (data) => {
               console.log('Model change', data);
            });
    }
  }




  // Project card
  @Component({
    selector: 'four',
    providers: [],
    styles: [ require('./four.scss') ],
    directives: [NgFor, MyDirective],
    template: `
        Hello, this is working! <br>
        <textarea mydir [(ngModel)]="pp.status"></textarea>
    `,
  })
  export class Four {
    @Input() pp: Array<any>;
    constructor() {
    }

  }

1 个答案:

答案 0 :(得分:4)

事实上,这是正确的行为。事实上,NgModel指令会在更新视图时触发update自定义事件(请参阅源代码中的此行https://github.com/angular/angular/blob/master/modules/angular2/src/common/forms/directives/ng_model.ts#L97):

viewToModelUpdate(newValue: any): void {
  this.viewModel = newValue;
  ObservableWrapper.callEmit(this.update, newValue);
}

您应该使用表单控件来实现此类处理:

@Component({
  selector: 'four',
  directives: [MyDirective],
  template: `
    Hello, this is working! <br>
    <textarea mydir [(ngModel)]="pp.status" [ngFormControl]="myCtrl"></textarea>
  `,
})
export class Four {
  @Input() pp;

  constructor() {
    this.myCtrl = new Control();
    this.myCtrl.valueChanges.subscribe(
      (data) => {
        console.log('Model change');
      });
  }
}

请参阅此plunkr:https://plnkr.co/edit/5E4JZhm32bu8rrPV9nEf?p=preview

修改

要实现您的期望,您需要利用与ngModel关联的控件并在其valueChanges属性中进行订阅。这样,当模型中的值和textarea中的值更新时,您将收到通知:

@Directive({
  selector: 'textarea[mydir]',
})
class MyDirective {
  constructor(@Optional() public model: NgModel){
    this.model.control.valueChanges.subscribe(data => {
      console.log('value updated - new value = '+data);
    });
  }
}

我更新了我的plunkr:https://plnkr.co/edit/5E4JZhm32bu8rrPV9nEf?p=preview