目前,我的DOM对象如下所示:
<div *ngIf="checkCam1Exists()">
<app-counter [index]="1"></app-counter>
</div>
在组件中,函数'checkCam1Exists()'如下所示:
checkCam1Exists(){
console.log("checkCam1ran");
if(this.cameraService.camera1 == null){
return false;
}
else{
return true;
}
}
其中cameraService是注入组件构造函数的服务,而camera1是cameraService中的对象。
我的问题在于让ngIf再次运行。 camera1对象从另一个服务(发出HTTP请求的dataService)中更新。如何触发ngIf再次运行?
我已阅读以下帖子: Triggering Angular2 change detection manually - 但Angular文档中提供的示例似乎没有涵盖如何检查组件类之外的变量(我需要检查服务变量)。
修改
我设法使用以下方法进行自动更改检测:
constructor(private ref: ChangeDetectorRef, private cameraService: CameraService, private toolbarService: ToolbarService) {
ref.detach();
setInterval(() => {
this.ref.detectChanges();
}, 5000);
}
虽然这感觉就像一种非常低效的方式。如何手动触发更改检测?
编辑2
在LucasTétreault的帮助下,我想我可能会在Angular 2区域之外进行初始点击事件,因为与应用程序的任何交互(在初始点击事件之后)都会导致ngIf检测到更改并再次开始工作。 我的问题必须在这里:
map.data.addListener('click', (event) => {
var mapElement = event.feature.getProperty('type');
switch(mapElement){
case 'classifiedroads':
var roadnumber = event.feature.getProperty('roadID');
map.data.revertStyle();
map.data.overrideStyle(event.feature, {
strokeWeight: 8
});
this.roadService.roadClicked(roadID);
break;
case 'cameras':
var cameraID = event.feature.getProperty('trafficID');
this.cameraService.cameraClicked(cameraID); //camera is initialised at this stage.
break;
default:
break;
}
});
我有一个使用JavaScript导入的Google Map对象(Angular2 Google Map项目存在一些限制,我被警告过,这就是我不使用它的原因)。此单击事件必须超出Angular 2区域,当我单击应用程序上的其他位置时,我会重新进入Angular 2区域并再次启动ngIf更改检测。
有没有办法可以手动强制进行ngIf更改检测?
答案 0 :(得分:1)
这最终对我有用。
我认为这与我所做的研究是正确的: 将Google Maps与AddListener一起使用意味着在Angular 2区域之外创建JavaScript侦听器。这意味着如果变量或某些内容发生变化,则不会触发Angular 2的变化检测。要解决这个问题,请在类的构造函数中注入NgZone:
constructor(private cameraService: CameraService, private ngZone: NgZone)...
使用NgZone的'.run()'重新进入Angular 2区域:
map.data.addListener('click', (event) => {
var mapElement = event.feature.getProperty('type');
switch(mapElement){
case 'cameras':
var cameraID = event.feature.getProperty('traffic_asset_bk');
this.ngZone.run(
() => this.cameraService.cameraClicked(station_key)
);
break;
default:
break;
}
});
答案 1 :(得分:0)
而不是手动trigerring你可以在html
中做到这一点ng-if =&#34; cameraService.camera1!= null&#34;
答案 2 :(得分:0)
我知道我迟到了,但是在Angular世界中有几种方法可以实现这样的事情。就个人而言,我更喜欢使用BehaviorSubject
观察。基本上在您的相机服务中,您将实例化一个BehaviorSubject可观察对象,然后在您的组件中订阅它,并在每次更新时将输出保存到组件中的属性,这将是您运行* ngIf的对象。我已经在几个项目中完成了这项工作并且运行良好。
<强> camera.service.ts 强>
private cameraStatus: BehaviorSubject<ModalProperties> = new BehaviorSubject<boolean>(false);
cameraStatus$ = this.cameraStatus.asObservable();
updateCameraStatus(status: boolean) {
this.cameraStatus.next(status);
}
<强>组件,其中,你更新相机-status.ts 强>
turnCameraOn() {
this._CameraService.updateCameraStatus(true);
}
您-component.component.ts 强>
componentVisibile: boolean
this_CameraService.cameraStatus$.subscribe(
_CameraStatus => {
this.componentVisible = _CameraStatus;
}
)