Angular 2 - 将组件绑定到多个值

Angular 2 - Binding Component to multiple values

我正在尝试在 Angular 2.

中实现日期范围选择器

我已经有一个可用的小部件,我必须 link 到 @angular/forms 子系统。

我想要的是能够将两个输出值(比如 rangeStartrangeEnd)绑定到包含表单状态中的两个不同属性。

有没有办法配置 NgModel 设置来完成此操作?

另一种方法是绑定 DateRange 类型的单个 属性:

type DateRange = {
    from: Date,
    to: Date
};

我不知道这是否可行。

关于如何完成此操作有什么建议吗?

编辑:

我有一个 jQuery 派生的 JS 组件,它公开了一个 onChange,如下所示:

component.on('change', (eventData) => {
  // here I have eventData.from and eventData.to as Date values
});

我想将这种处理程序集成到 Angular 友好的组件中。 但是,我不能简单地这样做:

<my-date-range-picker name"xyz" [(NgModel)]="aDateRangeValue"></my-date-range-picker>

因为,AFAICT,变化检测不适用于复合值。 我应该在我的组件中公开什么?两个 EventEmitter?我可以以某种方式利用 NgModel 吗?

您可以使用两个 Output 指令。

<my-date-range-picker name"xyz" [dateTo]="dateTo" [dateFrom]="dateFrom"></my-date-range-picker>

在你的组件中你会

import { Output } from '@angular/core';
.
.
@Output() dateTo: any; // EventEmitter, Subject, Number, String, doesn't matter ...
@Output() dateFrom: any;

这是使用 InputOutput

进行组件交互的参考

Component Interaction

如果您想创建自己的 ngModel 双向数据绑定,您应该这样做:

@Component()
export class MyComponent {

      myValue = 0;

      @Output()
      myValueChange = new EventEmitter();

      @Input()
      get myValue() {
             return this.myValue;
      }

      set myValue(val) {
           this.myValue= val;
           this.myValueChange.emit(this.myValue);
      }
}

现在您可以按如下方式使用它并使双向数据绑定生效:

<my-component [(myValue)]="someExpression"></my-component>

添加 link 到一个关于此的简单教程:http://www.angulartraining.com/blog/tutorial-create-your-own-two-way-data-binding-in-angular/

事实证明,您可以拥有任何类型的模型。

因此,我使用了 this article 中的基础 classes,这是最相关的:

export class ValueAccessorBase<T> implements ControlValueAccessor {  
  private innerValue: T;


  private changed = new Array<(value: T) => void>();
  private touched = new Array<() => void>();


  get value(): T {
    return this.innerValue;
  }


  set value(value: T) {
    if (this.innerValue !== value) {
      this.innerValue = value;
      this.changed.forEach(f => f(value));
    }
  }


  touch() {
    this.touched.forEach(f => f());
  }


  writeValue(value: T) {
    this.innerValue = value;
  }


  registerOnChange(fn: (value: T) => void) {
    this.changed.push(fn);
  }


  registerOnTouched(fn: () => void) {
    this.touched.push(fn);
  }
}

即使 T 是 class,具有 fromto 属性,这也适用,在我的例子中:

@Component(
  ...
)
class DateRangeComponent extends ValueAccessorBase<DateRange> {
  ... implementation

  // somewhere after the view init:
  jqueryComponent.on('change', (eventData) => {
   // here I have eventData.from and eventData.to as Date values
   this.value = {
     from: eventData.from,
     to: eventData.to
   };
  });
}

所以,如果其他人都偶然发现了这个问题,答案是:继续编写您自己的组件。

附带说明一下,当仅使用表单准备 Json 对象以在 Ajax 调用中发送时,此方法效果最佳。老式的表单编码提交将不那么线性。