ControlValueAccessor class 中的 writeValue 函数在 angular 2 自定义组件中调用一次
writeValue function in ControlValueAccessor class called once in angular 2 custom component
有一个自定义 angular2
组件,如下所示:
模板
<input class="form-control" id="searchbox" placeholder="شهر" (keyup)="search()" [(ngModel)]="name" autocomplete="off"/>
<div id="searchresult" *ngFor="let city of cities" (click)="cityselected(city)">
{{city.name}}
</div>
分量
@Component({
moduleId: module.id,
selector: 'city-search',
templateUrl: './city-search.component.html',
styleUrls: ['./city-search.component.css'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CitySearchComponent),
multi: true
}
]
})
export class CitySearchComponent implements OnInit, ControlValueAccessor{
cities: Array<City>;
name: string;
displaysearchbox: boolean;
errorMessage: string;
constructor(private cityService: CityService
, private helper : Helper) { }
ngOnInit() {
this.cities = new Array<City>();
this.displaysearchbox = false;
}
search(): void {
if (this.name) {
this.cityService.
search(this.helper.arabictopersian(this.name))
.subscribe(
data => {
this.cities = data as Array<City>
}
, error => this.errorMessage = <any>error);
}
}
cityselected(city: City): void {
this.name = city.name;
}
writeValue(value: any) { //just fire once to get the inital value
if (value !== undefined) {
this.name = value;
}
this.propagateChange(this.name);
}
propagateChange = (_: any) => { };
registerOnChange(fn) {
this.propagateChange = fn;
}
registerOnTouched() { }
}
如代码组件所示 class 实现 ControlValueAccessor
这是我如何使用它:
<form class="form-horizontal">
<city-search id="bc" name="city" [(ngModel)]="city"></city-search>
city:{{city}}<!--nothing happens -->
</form>
但是自定义组件有 1-way binding
而不是 2-way binding
..这个组件获得初始值但根本不会根据输入变化而改变..当我在浏览器上调试它时 writeValue
函数只是在加载时被触发,之后根本不会被触发。
我想你应该在选择新值时调用 propagateChange
方法
cityselected(city: any): void {
this.name = city.name;
this.propagateChange(this.name);
}
所以每当你想从 ControlValueAccessor
更新 ngControl 的值时,你应该调用你在 registerOnChange
方法
中设置的函数
registerOnChange(fn) {
this.propagateChange = fn;
}
通常这样的方法叫做onChange
函数https://github.com/angular/angular/blob/4.2.0-rc.1/packages/forms/src/directives/default_value_accessor.ts#L79
有一个自定义 angular2
组件,如下所示:
模板
<input class="form-control" id="searchbox" placeholder="شهر" (keyup)="search()" [(ngModel)]="name" autocomplete="off"/>
<div id="searchresult" *ngFor="let city of cities" (click)="cityselected(city)">
{{city.name}}
</div>
分量
@Component({
moduleId: module.id,
selector: 'city-search',
templateUrl: './city-search.component.html',
styleUrls: ['./city-search.component.css'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CitySearchComponent),
multi: true
}
]
})
export class CitySearchComponent implements OnInit, ControlValueAccessor{
cities: Array<City>;
name: string;
displaysearchbox: boolean;
errorMessage: string;
constructor(private cityService: CityService
, private helper : Helper) { }
ngOnInit() {
this.cities = new Array<City>();
this.displaysearchbox = false;
}
search(): void {
if (this.name) {
this.cityService.
search(this.helper.arabictopersian(this.name))
.subscribe(
data => {
this.cities = data as Array<City>
}
, error => this.errorMessage = <any>error);
}
}
cityselected(city: City): void {
this.name = city.name;
}
writeValue(value: any) { //just fire once to get the inital value
if (value !== undefined) {
this.name = value;
}
this.propagateChange(this.name);
}
propagateChange = (_: any) => { };
registerOnChange(fn) {
this.propagateChange = fn;
}
registerOnTouched() { }
}
如代码组件所示 class 实现 ControlValueAccessor
这是我如何使用它:
<form class="form-horizontal">
<city-search id="bc" name="city" [(ngModel)]="city"></city-search>
city:{{city}}<!--nothing happens -->
</form>
但是自定义组件有 1-way binding
而不是 2-way binding
..这个组件获得初始值但根本不会根据输入变化而改变..当我在浏览器上调试它时 writeValue
函数只是在加载时被触发,之后根本不会被触发。
我想你应该在选择新值时调用 propagateChange
方法
cityselected(city: any): void {
this.name = city.name;
this.propagateChange(this.name);
}
所以每当你想从 ControlValueAccessor
更新 ngControl 的值时,你应该调用你在 registerOnChange
方法
registerOnChange(fn) {
this.propagateChange = fn;
}
通常这样的方法叫做onChange
函数https://github.com/angular/angular/blob/4.2.0-rc.1/packages/forms/src/directives/default_value_accessor.ts#L79