Angular 5 通过组件传递 ngModel
Angular 5 pass ngModel through components
我创建了一个简单的组件,它包装了 bootstrap 的预输入控制器,因此它的配置方式符合我对应用程序的要求。该组件有一个 public 变量,selectedWorker
是预先输入的 ngModel
。
所以现在,当我在其他地方使用这个组件时,我想做这样的事情:
<app-worker-lookup [(ngModel)]="foo"></app-worker-lookup>
然后将调用者的 foo
变量绑定到具有选定值的查找组件的 public 变量。我不确定如何实现它。
为了使 ngModel
在组件上可用,您需要将组件实现为自定义表单控件。这应该相对简单明了,因为您的组件的表单行为与预先输入的表单行为相同。
Here's a nice article on how to do this, or a 如果你愿意的话。
需要注意的一件事是,为了正确实现双向绑定,您需要将 typeahead 组件的 [(ngModel)]
属性拆分为 [ngModel]="selectedWorker" (ngModelChange)="onChange($event)"
,以便您可以调用 writeValue()
在 onChange
方法中。
要在您的组件中使用 ngModel,您的 class 必须实施 ControlValueAccessor 并将组件添加到提供令牌
组件
@Component({
selector: 'component',
templateUrl: '../component.html',
styleUrls: ['../component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => Component),
multi: true
}
]
})
export class Component implements ControlValueAccessor {
//
// Now add ngModel property binding
@Input() ngModel : NgModel;
....
//
// ControlValueAccessor implementation
writeValue(value:any) {
this.value = value;
}
registerOnChange(fn) {
this.propagateChange = fn;
}
registerOnTouched(fn){
}
private propagateChange = (_:any) => {};
}
我创建了一个简单的组件,它包装了 bootstrap 的预输入控制器,因此它的配置方式符合我对应用程序的要求。该组件有一个 public 变量,selectedWorker
是预先输入的 ngModel
。
所以现在,当我在其他地方使用这个组件时,我想做这样的事情:
<app-worker-lookup [(ngModel)]="foo"></app-worker-lookup>
然后将调用者的 foo
变量绑定到具有选定值的查找组件的 public 变量。我不确定如何实现它。
为了使 ngModel
在组件上可用,您需要将组件实现为自定义表单控件。这应该相对简单明了,因为您的组件的表单行为与预先输入的表单行为相同。
Here's a nice article on how to do this, or a
需要注意的一件事是,为了正确实现双向绑定,您需要将 typeahead 组件的 [(ngModel)]
属性拆分为 [ngModel]="selectedWorker" (ngModelChange)="onChange($event)"
,以便您可以调用 writeValue()
在 onChange
方法中。
要在您的组件中使用 ngModel,您的 class 必须实施 ControlValueAccessor 并将组件添加到提供令牌
组件
@Component({
selector: 'component',
templateUrl: '../component.html',
styleUrls: ['../component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => Component),
multi: true
}
]
})
export class Component implements ControlValueAccessor {
//
// Now add ngModel property binding
@Input() ngModel : NgModel;
....
//
// ControlValueAccessor implementation
writeValue(value:any) {
this.value = value;
}
registerOnChange(fn) {
this.propagateChange = fn;
}
registerOnTouched(fn){
}
private propagateChange = (_:any) => {};
}