Angular 5 обновлений модели после завершения событий - PullRequest
0 голосов
/ 03 июля 2018

Проблема

Я использую Angular 5 и создал компонент, который имеет 3 элемента управления

<ss-multiselect-dropdown id="type" formControlName="type" (ngModelChange)="onChange('type')"></ss-multiselect-dropdown>

<input id="caption" type='text' formControlName='caption' (input)="onChange('caption')" />

<custom-uploader formControlName="url" (input)="onChange('url')"></custom-uploader>

когда onChange вызывается из ss-multiselect-dropdown или input модель показывает ожидаемое значение при шаге по методу onChange. Но когда onChange вызывается custom-uploader, старое значение (значение, существовавшее до вызова onChange) все равно применяется к модели.

будет ясно:

под ожидаемым значением я имею в виду значение, которое я выбираю или вводю для этого элемента управления

Я пытался изменить

<custom-uploader formControlName="url" (input)="onChange('url')"></custom-uploader>

до

<custom-uploader formControlName="url" (change)="onChange('url')"></custom-uploader>

и

<custom-uploader formControlName="url" (ngModelChange)="onChange('url')"></custom-uploader>

похоже, что модель обновляется после завершения onChange. Что я сделал не так?

код

заказ uploader.component.html

<div class="form-group">
    <div class="input-group file-upload">
        <input type="file" (change)="fileChange(input)" #input class="file-upload-btn"/>
        <input type="text" class="form-control" placeholder="Choose a file..." value="{{file}}">
        <i class="fa fa-times delete-file" (click)="removeFile()" *ngIf="file"></i>
        <span class="input-group-btn">
            <button class="btn btn-primary" type="button"><i class="fa fa-upload"></i></button>
        </span>
    </div>
</div>

Custom-uploader.component.ts

import { Component, ViewEncapsulation, ChangeDetectorRef, ViewChild, Output, EventEmitter, forwardRef, SimpleChanges, OnChanges } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor, NG_VALIDATORS } from '@angular/forms';

import { Ng2ImgMaxService } from 'ng2-img-max';

@Component({
  selector: 'custom-uploader',
  encapsulation: ViewEncapsulation.None,
  templateUrl: './file-uploader.component.html',
  styleUrls: ['./file-uploader.component.scss'],
  providers: [ 
    { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => FileUploaderComponent), multi: true }
  ]
})
export class FileUploaderComponent implements OnChanges, ControlValueAccessor  {

    @ViewChild('input') fileUploaderInput: any;

    public file:any;
    public propagateChange = (_: any) => {};

    constructor(
        private _changeDetectorRef: ChangeDetectorRef,
        private _ng2ImgMaxService: Ng2ImgMaxService
    ) { }   

    writeValue(obj: any): void 
    { 
        this.file = obj;
        this._changeDetectorRef.detectChanges();
    }
    registerOnChange(fn: any): void {
        this.propagateChange = fn;
    }
    registerOnTouched(fn: any): void { }
    setDisabledState?(isDisabled: boolean): void { }
    ngOnChanges(changes: SimpleChanges): void { }

    fileChange(input){
        const reader = new FileReader();
        if (input.files.length) {       
            this.file = input.files[0].name;     
            this.propagateChange(this.file);   
            this.fileUploaderInput.nativeElement.value = "";    
        }
    }

    removeFile():void{
        this.file = '';
        this.propagateChange(this.file);       
    }

}

1 Ответ

0 голосов
/ 04 июля 2018

Синтаксис в скобках, например (change), относится к EventEmitter, который генерирует событие при изменении значения. Вы должны реализовать это самостоятельно в своем FileUploaderComponent, например:

@Output() change = new EventEmitter<string>();
...
fileChange(input){
    const reader = new FileReader();
    if (input.files.length) {
        this.file = input.files[0].name;
        this.change.next(this.file);
        ...  
    }
}

Тогда где вы создаете его экземпляр:

Шаблон:

<custom-uploader formControlName="url" (change)="onChange($event)"></custom-uploader>

Машинопись:

onChange(fileName: string) {
    //Whatever you want to do with the fileName
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...