我发现了一个奇怪的问题,涉及bootstrapjs模态和angular2。我有一个绑定到引导程序模式的html的组件:
// ... lots of imports here
@Component({
selector: 'scrum-sessions-modal',
bindings: [ScrumSessionService, ScrumSessionRepository, ScrumModuleDataContext, ElementRef]
})
@View({
templateUrl: 'templates/modals/scrumSessions.modal.html',
styleUrls: ['']
})
export class ScrumSessionsModalComponent {
private _elementRef: ElementRef;
public sessions: ScrumSession[];
constructor(scrumSessionsProxy: ScrumSessionsProxy, scrumSessionService: ScrumSessionService, elementRef: ElementRef) {
this._proxy = scrumSessionsProxy;
this._scrumSessionService = scrumSessionService;
this._elementRef = elementRef;
// This is the bootstrap on shown event where i call the initialize method
jQuery(this._elementRef.nativeElement).on("shown.bs.modal", () => {
this.initialize();
});
jQuery("#scrumSessionsModal").on("hidden.bs.modal", () => {
this.cleanup();
});
}
public initialize() {
// Start our hub proxy to the scrumsessionshub
this._proxy.start().then(() => {
// Fetch all active sessions;
this._scrumSessionService.fetchActiveSessions().then((sessions: ScrumSession[]) => {
// This console.log is being shown, however the sessions list is never populated in the view even though there are active sessions!
console.log("loaded");
this.sessions = sessions;
});
});
}
// Free up memory and stop any event listeners/hubs
private cleanup() {
this.sessions = [];
this._proxy.stop();
}
}
在此模式中,我在构造函数中有一个事件侦听器,用于检查何时显示模式。在执行此操作时,它将调用初始化函数,该函数将加载将在模式中显示的初始数据。
模态的html如下所示:
<div class="modal fade" id="scrumSessionsModal" tabindex="-1" role="dialog" aria-labelledby="scrumSessionsModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Actieve sessies </h4>
</div>
<div class="modal-body">
<table class="table">
<tr>
<th>Id</th>
<th>Maker</th>
<th>Start datum</th>
<th>Aantal deelnemers</th>
</tr>
<tr *ngFor="#session of sessions">
<td>
{{ session.id }}
</td>
<td>
test
</td>
<td>
test
</td>
<td>
test
</td>
</tr>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
我遇到的问题是,由fetchactivesessions函数填充的session变量在视图中未更新。我在获取完成方法上放了一个调试器,并由于一个scrumsession对象的结果而调用它。
但是,当我删除on(“ shown.bs.modal”)事件侦听器,并简单地将对initialize()的调用放在5秒钟的setTimeout函数中,然后打开模式时,将正确填充会话列表。
仅当我将初始化调用放入bootstrap显示的事件的回调中时才会发生。就像当调用在jquery回调内部时,它停止检查更改。有人知道这笔交易吗?我当然可以在构造函数中调用initialize,但是我宁愿从bootstrap在显示的事件上调用它。
我已经在以下位置发布了该应用程序的最新版本以进行调试:http : //gbscrumboard.azurewebsites.net/
通过易于使用的服务包装以上解决方案:
更新:如果您使用的是rxjs-6,则有重大更改,您将不得不
import { fromEvent } from 'rxjs';
..
和使用
..
fromEvent(document, BsEventsService.BS_COLLAPSIBLE_SHOWN);
代替
Observable.fromEvent(document, BsEventsService.BS_COLLAPSIBLE_SHOWN);
bs-events.service.ts
import { Subject, Observable, Subscription } from 'rxjs';
import { Injectable } from '@angular/core';
@Injectable() export class BsEventsService { private static BS_COLLAPSIBLE_SHOWN: string = 'shown.bs.collapse'; private static BS_COLLAPSIBLE_HIDDEN: string = 'hidden.bs.collapse';
constructor() {
this.registerEvent(BsEventsService.BS_COLLAPSIBLE_SHOWN);
this.registerEvent(BsEventsService.BS_COLLAPSIBLE_HIDDEN);
}
onCollapsibleShown(): Observable<Event> {
return Observable.fromEvent(document, BsEventsService.BS_COLLAPSIBLE_SHOWN);
}
onCollapsibleHidden(): Observable<Event> {
return Observable.fromEvent(document, BsEventsService.BS_COLLAPSIBLE_HIDDEN);
}
private registerEvent(event) {
var script = document.createElement('script');
script.innerHTML = "eventRelay('" + event + "');"
document.body.appendChild(script);
}
}
index.html
<app-root></app-root>
..
<!-- relay bootstrap events to angular - start -->
<script>
function eventRelay(bs_event) {
$('body').on(bs_event, function ($event) {
const customEvent = document.createEvent('Event');
customEvent.initEvent(bs_event, true, true);
let target_id = '#' + $event.target.id;
$(target_id)[0].dispatchEvent(customEvent);
});
}
</script>
<!-- relay bootstrap events to angular - end -->
..
</body>
零件
import { BsEventsService } from './service/bs-events.service';
import { Subject, Observable, Subscription } from 'rxjs';
..
private onCllapsibleShownSubject: Subscription;
private onCllapsibleHiddenSubject: Subscription;
..
constructor(.., private bsEventsService: BsEventsService) {
..
}
ngOnInit() {
this.onCllapsibleShownSubject = this.bsEventsService.onCollapsibleShown().subscribe((event: any) => {
console.log('shown: ' + event.target.id);
});
this.onCllapsibleHiddenSubject = this.bsEventsService.onCollapsibleHidden().subscribe((event: any) => {
console.log('hidden: ' + event.target.id);
});
}
ngOnDestroy() {
this.onCllapsibleShownSubject.unsubscribe();
this.onCllapsibleHiddenSubject.unsubscribe();
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句