2016-10-13 120 views
0

目前,我的DOM對象是這樣的:角2手動觸發ngIf

<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); 
    } 

雖然這感覺就像是一個令人難以置信的低效率的方式做到這一點。我如何手動觸發更改檢測?

EDIT 2

與盧卡斯Tétreault幫助,我想我可能會去外面初始click事件的角2區,與應用程序的任何互動(後最初的單擊事件)的原因ng如果檢測到更改並再次開始工作。 我的問題必須躺在這裏:

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進口了谷歌地圖對象(有我爲什麼不使用與我被警告不要將Angular2谷歌地圖項目限制的)。此點擊事件必須超出Angular 2區域,當我在應用程序的其他位置單擊時,我將重新進入Angular 2區域,並且ngIf更改檢測再次啓動。

有沒有辦法可以手動強制ngIf變化檢測?

回答

0

除了手動trigerring你能做到這一點正好在HTML

NG-IF =的 「cameraService.camera1!= NULL」

+0

我很想+1你的回答,因爲我沒有意識到我可以直接從HTML引用注入的服務(所以謝謝你的建議!),但不幸的是,我仍然有同樣的問題,其中ngIf仍然需要手動觸發一旦cameraService對象發生變化。 – fila

+0

組件的更改檢測將會檢測到服務的更改: http://plnkr.co/edit/lxgAJs –

+0

因此,使用您的建議,我進一步研究了它。我要在Angular 2區域之外進行初始點擊(使用JavaScript導入的Google Map對象)。當我點擊Google Map中的靜態對象時,JavaScript會處理點擊事件(由於Google地圖),即使變量已更新,也不會發生變化檢測。當我在任何地方與網站進行交互的時候(字面上通過點擊其他任何地方),視圖更新和相機出現。我想我必須查看ngZone的地圖點擊事件。 – fila

1

這對我來說到底有什麼工作。

我認爲這樣做對我所做的研究是正確的: 使用帶有AddListener的Google Maps意味着在Angular 2區域之外創建JavaScript偵聽器。這意味着如果變量或其他內容發生變化,Angular 2的變化檢測將不會被觸發。爲了解決這個問題,在類的構造函數中注入NgZone:

constructor(private cameraService: CameraService, private ngZone: NgZone)... 

使用NgZone的'。運行()」重新進入角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; 
     } 
    }); 
0

我知道我遲到了,但也有在角世界幾個方式來實現這樣的事情。就個案而言,我寧願使用BehaviorSubject observable。基本上在攝像頭服務中,您將實例化一個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; 
    } 
)