我有一个角度组件,实际上是一个自举面板。
export class ExerciseComponent implements OnInit {
@Input() exercise:Exercise;
@Input() index:number;
@Input() first:boolean;
@Input() last:boolean;
@Input() active:boolean;
@Input() selected:boolean;
constructor(private data:ApiDataService, private route:ActivatedRoute) {
}
toggleActive(e){
let show = (e.type=='show');
this.active = show;
}
}
使用模板:
<div class="panel-heading">
<div>
<h5 class="panel-title">
<a data-toggle="collapse" data-parent="#accordionexercises"
class="accordion-link" href="#collapse{{ exercise.id }}">
{{ exercise.title }} </a>
</h5>
<div class="pull-right">
<i *ngFor="let n of exercise.difficulty | fill" class="fa fa-star"></i>
</div>
</div>
<exercise-preview [hidden]="active" [e]="exercise"></exercise-preview>
</div>
<div id="collapse{{ exercise.id }}" [ngClass]="{'panel-collapse collapse':true, 'in':selected}"
collapseControl (collapseStatus)="toggleActive($event)">
<div class="panel-body">
<div class="row">
<div class="col-md-12">
<div *ngIf="exercise.image" class="pull-right">
<img src="http://localhost:8000{{ exercise.image.file }}"/>
</div>
<div [innerHtml]="exercise.exText"></div>
</div>
</div>
</div>
</div>
和一个名为collapseControl
的指令,它检测引导崩溃事件(Jquery)并将它们传播给collapseStatus($event)
中的组件:
@Directive({
selector: '[collapseControl]'
})
export class CollapseControlDirective{
@Output() collapseStatus: EventEmitter<any>;
constructor(el: ElementRef) {
this.collapseStatus = new EventEmitter();
Observable
.fromEvent($(el.nativeElement), 'hide.bs.collapse show.bs.collapse')
.subscribe(e=> this.collapseStatus.emit(e));
}
}
一切正常,事件传播到父级,this.active
根据事件设置,但UI未更新(请注意[hidden]
组件上的<exercise-preview/>
属性)。
如果我只是将(collapseStatus)="toggleActive($event)"
更改为(click)="toggleActive($event)"
,一切正常。这必须做一些角度变化检测,但我无法弄清楚我做错了什么。
答案 0 :(得分:1)
Angular并不知道通过Observable.fromEvent
订阅所做的更改,因为这不会在zone内发生。您可以使用NgZone
在区域内运行代码。 e.g:
import { NgZone } from '@angular/core';
// ...
constructor(el: ElementRef, ngZone: NgZone) {
this.collapseStatus = new EventEmitter();
Observable
.fromEvent($(el.nativeElement), 'hide.bs.collapse show.bs.collapse')
.subscribe(e => {
ngZone.run(() => this.collapseStatus.emit(e));
});
}
你可能最好使用例如ng-bootstrap,如果可以的话,为了在使用可折叠物等时获得更像Angular的体验,等等。