【问题标题】:writeValue function in ControlValueAccessor class called once in angular 2 custom componentControlValueAccessor 类中的 writeValue 函数在 Angular 2 自定义组件中调用一次
【发布时间】:2017-05-30 11:46:23
【问题描述】:

有一个自定义的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() { }
    }

如代码所示,组件类实现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 函数只是在加载和之后根本不会被解雇。

【问题讨论】:

    标签: angular angular-ngmodel angular2-ngmodel


    【解决方案1】:

    我想你应该在选择新值时调用propagateChange 方法

    cityselected(city: any): void {
      this.name = city.name;
      this.propagateChange(this.name); 
    }
    

    Plunker Example

    因此,每当您想从 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

    【讨论】:

    • 我按照你说的做了,但还是不行。实际上,writeValue 必须在value 发生任何更改后调用,然后在writeValue 内部调用propagateChange。 .problem 是首先必须调用writeValue 但它不是
    • 在您的 plunker 示例中,在组件中输入一些内容,您将看到新值不出现
    • 选择后会出现新值
    猜你喜欢
    • 2019-01-05
    • 2020-01-08
    • 2018-06-29
    • 1970-01-01
    • 2018-03-26
    • 2017-11-20
    • 2019-01-18
    • 2019-11-02
    • 2017-10-27
    相关资源
    最近更新 更多