Вы идете об этом таким образом, который работает против каркаса и будет вести к большому воплю и скрежет зубов.
Прямо сейчас вы вручную подписываетесь на наблюдаемый - 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
, и вы не должны написать одну строку императивного кода Сделай это.
Если вы обновите свой вопрос, чтобы показать мне, как вызывается 'onProgress', я могу сделать свой ответ более полезным для вас - я подозреваю, что здесь используется более глубокий анти-шаблон. – drewmoore
Добавлена часть onProgress. Он извлекается через xhr onprogress, на который я подписался. – Dreamlines
Я был прав :-) Только секунду, и я обновлю – drewmoore