ngOnChanges работает только когда есть действие

Я создаю свой собственный компонент загружаемого файла, используя XMLHttpRequest, и все работает нормально... Единственная проблема, которую я имею, - это то, что я создаю метод обратного вызова, который обновляет ход загрузки, чтобы пользователь мог видеть процент.

Если я сделаю consolo.log() из progrees, я смогу увидеть, как он увеличится с 0 до 100.

Но экран не отражает это... У меня есть эта функция в этом компоненте:

ngOnChanges(){
if(this.progress == 100){
  this.progress = 0;
  this.uploading = false;
}
 }

И у меня есть метод, чтобы получить последнее значение прогресса (который запускается из родительского компонента)

public updateProgress(progress : number){
    this.progress = progress;
    console.log(this.progress);
    if(this.progress == 100)
      this.uploading = false;
  }

И если шаблон у меня есть

    <div *ngIf="uploading" class="uploading">
    <progressbar [max]="100" [value]="progress"><span style="color:white; white-space:nowrap;">{{progress}} / {{100}}</span></progressbar>
</div>

Таким образом, индикатор выполнения не увеличивает прогресс, даже когда в консоли я вижу, что значение "прогресса" меняется.

Но спустя долгое время я обнаружил, что если щелкнуть мышью в ЛЮБОМ разделе экрана, запускается ngOnChange, а индикатор выполнения обновляется... Итак, если я начинаю делать щелчки во время загрузки файла, я в состоянии видеть прогресс...

4 ответа

Решение

Впрыскивать

constructor(private cdRef:ChangeDetectorRef){}

и после обновления progress, вызов

this.progress = ...;
this.cdRef.markForCheck();

или же

this.progress = ...;
this.cdRef.detectChanges();

В качестве альтернативы вы можете ввести NgZone

constructor(private zone:NgZone){}

и сделать обновление с

this.zone.run(() => this.progress = ...);

Это приводит к тому, что обнаружение изменений запускается, когда код Angular вызывается извне Angular таким образом, что Angular не может его распознать.

Я думаю, что вы пропустили реализует OnChanges

import {Component,OnChanges, SimpleChange} from '@angular/core';
  export class yourcomponet implements OnChanges {
   ngOnChanges(changes: {[propKey: string]: SimpleChange})
    {
      // Here goes your logic
   }
}

Из примера я вижу, что в вашем дочернем компоненте вы вводите свойство с именем value, но в процессе проверки прогресса. удостоверьтесь, что вы помещаете это в местную собственность прогресса. ngOnChanges() будет срабатывать каждый раз, когда изменяется любое входное свойство. попробуйте напечатать console.log в вашем ngOnChanges () перед любым оператором if() и проверьте значение

Поскольку вы не перечислили весь код, неясно, как взаимодействуют ваши родительские / дочерние компоненты. С одной стороны, кажется, что и родитель, и ребенок имеют переменную прогресса. Зачем?

Другой вопрос: почему вы используете ngOnChanges?

Если ваш дочерний компонент знает текущее значение прогресса, создайте переменную @Output в дочернем элементе и отправляйте событие при каждом изменении прогресса.

@Output() currentProgres: EventEmitter <number> = new EventEmitter();
...
this.currentProgress.emit(progress);

В родителе слушайте эти события:

<progressbar [max]="100" (currentProgress)="updateProgress($event)">
...
updateProgress(progress : number){}

Родитель может иметь переменную showProgress, связанную с пользовательским интерфейсом, поэтому он будет обновляться автоматически.

Другие вопросы по тегам