Angular 2 - 将组件绑定到多个值
Angular 2 - Binding Component to multiple values
我正在尝试在 Angular 2.
中实现日期范围选择器
我已经有一个可用的小部件,我必须 link 到 @angular/forms
子系统。
我想要的是能够将两个输出值(比如 rangeStart
和 rangeEnd
)绑定到包含表单状态中的两个不同属性。
有没有办法配置 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;
这是使用 Input
和 Output
进行组件交互的参考
如果您想创建自己的 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,具有 from
和 to
属性,这也适用,在我的例子中:
@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 调用中发送时,此方法效果最佳。老式的表单编码提交将不那么线性。
我正在尝试在 Angular 2.
中实现日期范围选择器我已经有一个可用的小部件,我必须 link 到 @angular/forms
子系统。
我想要的是能够将两个输出值(比如 rangeStart
和 rangeEnd
)绑定到包含表单状态中的两个不同属性。
有没有办法配置 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;
这是使用 Input
和 Output
如果您想创建自己的 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,具有 from
和 to
属性,这也适用,在我的例子中:
@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 调用中发送时,此方法效果最佳。老式的表单编码提交将不那么线性。