2016-04-17 3 views
5

У меня есть простой компонент, который просто отображает индикатор выполнения.Просмотр углового2 не обновляется при изменении переменных

Инициализирует штраф, и прогресс переходит к нему просто отлично, но шаблон не обновляется новыми значениями.

import {Component} from 'angular2/core'; 

@Component({ 
    selector : 'progress-bar', 
    template : ` 
    <div class="progress-container"> 
     <div>{{currentProgress}}</div> 
     <div [style.width.%]="currentProgress" class="progress"></div> 
    </div> 
    `, 
    styles: [ 
    '.progress-container {width: 100%; height: 5px}', 
    '.progress {background-color: #8BC34A; height:5px}' 
    ] 
}) 

export class ProgressBar { 
    currentProgress: number; 

    constructor() { 
    this.currentProgress = 0; 
    } 

    onProgress(progress: number) { 
    console.log(progress) //consoles correct percentages 
    this.currentProgress = progress; 
    } 

    reset() { 
    console.log(this.currentProgress) //is 100 
    this.currentProgress = 0; 
    } 
} 
~ 

В других

ngOnInit() { 
    this.httpFileService.progress$.subscribe((progress: number) => this.onProgress(progress)); 
    } 

    onProgress(progress: number) { 
    this.progressBar.onProgress(progress*100); 
    } 

Я чувствую, что я что-то очень не хватает меры по исправлению.

+0

Если вы обновите свой вопрос, чтобы показать мне, как вызывается 'onProgress', я могу сделать свой ответ более полезным для вас - я подозреваю, что здесь используется более глубокий анти-шаблон. – drewmoore

+0

Добавлена ​​часть onProgress. Он извлекается через xhr onprogress, на который я подписался. – Dreamlines

+0

Я был прав :-) Только секунду, и я обновлю – drewmoore

ответ

11

Вы идете об этом таким образом, который работает против каркаса и будет вести к большому воплю и скрежет зубов.

Прямо сейчас вы вручную подписываетесь на наблюдаемый - httpFileService.progress$ - и затем вручную обновляете свойство на дочернем компоненте ProgressBar, минуя механизм обнаружения изменений углов - именно поэтому пользовательский интерфейс не обновляется. Вы установили ручное обнаружение изменения огня после установки этого свойства, и пользовательский интерфейс будет обновляться, как и ожидалось, - но опять же, вы будете работать против фреймворка, поэтому давайте посмотрим, как с ним работать:

Я предполагаю, что «в другом месте» является родителем вашего компонента ProgressBar - назовем это ElsewhereComponent.

@Component({ 
    selector: 'elsewhere', 
    directives: [ProgressBar], 
    template: ` 
    <div> 
     <progress-bar [currentProgress]="httpFileService.progress$"></progress-bar> 
    </div> 
    ` 
}) 
class ElsewhereComponent { 
    // you can remove the ngOnInit and onProgress functions you posted 
    // you also don't need a reference to the child ProgressBar component 
    // ... whatever else you have in this class ... 
} 

Самое главное, чтобы отметить здесь является добавление [currentProgress] на progress-bar компонента: Это говорит Угловое, что есть входное свойство с именем currentProgress на этот компонент, который должен быть связан с httpFileService.progress$.

Но вы теперь лгали до углового - в его нынешнем виде ProgressBar не имеет входов вообще, и угловой расскажет вам об этом, когда он попытается связать это несуществующее свойство с заданным значением. Таким образом, нам нужно добавить свойство ввода, а также предпочтительный способ сделать это с Input() декоратора:

@Component({ 
    selector : 'progress-bar', 
    pipes: [AsyncPipe] //import this from angular2/core 
    template : ` 
    <div class="progress-container"> 
     <div>{{currentProgress | async}}</div> 
     <div [style.width.%]="currentProgress | async" class="progress"></div> 
    </div> 
    ` 
}) 
export class ProgressBar { 
    @Input() currentProgress: Observable<number>; 
    ... 
    constructor(){ 
    // remove the line you have in here now 
    } 

} 

Есть два важных отличия здесь, чтобы отметить: во-первых, @Input() говорит Угловое, что currentProgress является свойством ввода. Мы также изменили тип этого свойства от number до Observable<number> - это не является строго необходимым, но это полезно, потому что позволяет второй критической разницы:

AsyncPipe была добавлена ​​компонента pipes, и используется в обоих привязки его шаблонов к currentProgress. Это полезно, потому что это говорит о том, что он угрюм, чтобы обрабатывать все грязные возможности подписки на Observable и обновлять пользовательский интерфейс каждый раз, когда он испускает новое значение.

И это все, что нужно: и ширина панели и текст над ним теперь будет обновляться автоматически, чтобы отразить значения, испускаемых из ваших httpFileService, и вы не должны написать одну строку императивного кода Сделай это.

+0

Я реализую выше, но проблема, с которой я столкнулась, - это индикатор прогресса, который не обновляется автоматически. Однако, если я нажимаю на панель, она работает хорошо. на панели отобразится текущее значение из наблюдаемых. Есть идеи? – Hammer

+0

@ Hammer, что вы описываете, является проблемой обнаружения изменений – drewmoore

+0

Да. Согласитесь, но я сравниваю коды с u, разделяемыми здесь, без всякой подсказки. Я вставляю свой код здесь, оцениваю, если вы можете помочь взглянуть? Tks. http://stackoverflow.com/questions/37046757/ui-is-not-updated-automatically-when-value-is-available-from-the-observable – Hammer

Смежные вопросы