2017-06-15 59 views
1

在我看來沒有更新我有這樣的:

<div class="tab-loading-container" ng-if="mapStatus.loading =='true'"> 
    <div class="tab-loading">Loading map</div> 
</div> 

在我的控制,我有:

$scope.mapStatus = {}; 

,然後將該更新使用範圍VAR各種功能由ng-if,當滿足一定的條件,如等離線是(例如:

function enableMap() { 
    $scope.mapStatus.loading = false; 
} 

我的問題是儘管範圍var正在得到正確更改(通過良好的'console.log和角度chrome擴展名確認),視圖中的ng-if從不更新/被添加/刪除以顯示/刪除div。

我使用$應用(雖然我對它的理解是不是很大)嘗試,例如:

function enableMap() { 
    $scope.$apply(function() { 
     $scope.mapStatus.loading = false; 
    }); 
} 

,但拋出的錯誤,如Error: [$rootScope:inprog] $apply already in progress

覺得我失蹤明顯的東西:(


更多的代碼的要求:

angular.module('app.case.controller', []) 
.controller('CaseController', function($rootScope, $scope, $state, $stateParams, $filter, casesFactory, $ionicActionSheet, $ionicModal, $ionicTabsDelegate, $ionicLoading, ConnectivityMonitor) { 

/// Other non related code 

// location map - refactor into a factory 
    $scope.mapStatus = {}; 

    function initMap() { 
     var pos = { 'lat': 52.6136149, 'lng': -1.1936672 }; 

     var latLng = new google.maps.LatLng(pos.lat, pos.lng); 

     var mapOptions = { 
      center: latLng, 
      zoom: 15, 
      mapTypeId: google.maps.MapTypeId.ROADMAP, 
      fullscreenControl: false, 
      mapTypeControl: false 
     }; 

     $scope.map = new google.maps.Map(document.getElementById('map'), mapOptions); 

     google.maps.event.trigger(map, 'resize'); 

     //Wait until the map is loaded 
     google.maps.event.addListenerOnce($scope.map, 'idle', function() { 

      enableMap(); 

      console.log('map loaded'); 

      var marker = new google.maps.Marker({ 
       map: $scope.map, 
       animation: google.maps.Animation.DROP, 
       position: latLng 
      }); 

      google.maps.event.trigger(map, 'resize'); 

      $scope.map.setCenter(latLng); 

     }); 
    } 

    function loadGoogleMaps() {  
     $scope.mapStatus.loading = true; 

     // This function will be called once the SDK has been loaded 
     window.mapInit = function(){ 
      initMap(); 
     }; 

     // Create a script element to insert into the page 
     var script = document.createElement('script'); 
     script.type = 'text/javascript'; 
     script.id = 'googleMaps'; 
     script.src = 'https://maps.googleapis.com/maps/api/js?key=XXX&callback=mapInit'; 

     document.body.appendChild(script); 
    } 

    function enableMap() { 
     $scope.mapStatus.loading = false; 
     $scope.mapStatus.offline = false; 
    } 

    function disableMap() { 
     $scope.mapStatus.offline = true; 
    } 

    function checkLoaded() { 
     if (typeof google == 'undefined"' || typeof google.maps == 'undefined') { 
      loadGoogleMaps(); 
     } else { 
      enableMap(); 
     }  
    } 

    function addConnectivityListeners() { 

     if (ionic.Platform.isWebView()) { 

      // Check if the map is already loaded when the user comes online, if not, load it 
      $rootScope.$on('$cordovaNetwork:online', function(event, networkState) { 
       checkLoaded(); 
      }); 

      // Disable the map when the user goes offline 
      $rootScope.$on('$cordovaNetwork:offline', function(event, networkState) { 
       disableMap(); 
      }); 

     } else { 

      //Same as above but for when we are not running on a device 
      window.addEventListener("online", function(e) { 
       checkLoaded(); 
      }, false);  

      window.addEventListener("offline", function(e) { 
       disableMap(); 
      }, false); 
     } 
    } 

    function showMap() { 

     console.log('showMap() called'); 

     if (typeof google == 'undefined' || typeof google.maps == 'undefined') { 

      console.warn("Google Maps SDK needs to be loaded"); 

      disableMap(); 

      if (ConnectivityMonitor.isOnline()){ 
       loadGoogleMaps(); 
      } 
     } 
     else { 
      if (ConnectivityMonitor.isOnline()){ 
       initMap(); 
       enableMap(); 
      } else { 
       disableMap(); 
      } 
     } 

     addConnectivityListeners(); 
    } 

    $scope.initMap = function() { 
     showMap(); 
    }; 

要確認範圍瓦爾正在這裏改變是從AngularJS Chrome擴展程序截圖:

enter image description here

+7

你爲什麼用** **字符串''true''一個比較** **布爾值,只是把它寫爲'NG-IF = 「mapStatus.loading」' – George

+0

哎呦,好點。但是,在更改爲'mapStatus.loading'之後,即使控制器中的var被設置爲false(當滿足某些條件時),div也會始終顯示。 –

+1

我想你應該使用'ng-show'而不是'ng-if' – Xatyrian

回答

0

所以它只是一個布爾值,而不是相對於一個字符串,我已經改變了它。 您是否曾經設置$scope.mapStatus.loadingtrue?否則,它永遠不會顯示,因爲它永遠是錯誤的。

var myApp = angular.module('myApp', []); 
 

 
function MyCtrl($scope) { 
 
    $scope.mapStatus = {}; 
 

 
    $scope.hideMe = function() { 
 
    $scope.mapStatus.loading = false; 
 
    } 
 

 
    $scope.showMe = function() { 
 
    $scope.mapStatus.loading = true; 
 
    } 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<div ng-app="myApp"> 
 
    <div ng-controller="MyCtrl"> 
 
    <div class="tab-loading-container" ng-if="mapStatus.loading"> 
 
     <div class="tab-loading">Loading map</div> 
 
    </div> 
 
    <button ng-click="hideMe()">Hide Me</button> 
 
    <button ng-click="showMe()">Show Me</button> 
 
    </div> 
 
</div>

+0

感謝您的回覆,我仍然有問題。我添加了更多代碼以顯示我將其設置爲true的位置 –

+0

將此標記爲正確的答案,因爲這是一個問題,另一個問題是邏輯問題 –

1

我不知道這是否會解決您的問題或沒有,但你得太遠在此之前,我建議你擺脫引用到$範圍和使用controllerAs。我已經看到很多實例,直接添加到$ scope的對properties/methods的引用沒有特別原因。 Specificially我建議你:

  • 刪除,你必須注入$範圍,
  • 添加var ctrl=this到你的構造函數的代碼在你的控制器,
  • 改變一切以$範圍在控制器的引用ctrl,
  • add controllerAs vm到你加載你的控制器的地方,
  • 把你視圖中所有對控制器屬性的引用都改爲前綴vm。

你可能會很幸運,這可能只是解決你的問題,但無論如何,這仍然是一個更好的方式來使用控制器。 (如果你使用的是Angular 1.5+,我真的建議你在你太過分的情況下將它重構爲一個組件。)

0

(我張貼此答案的情況下,有人採用了棱角分明V2 +)談到過這個問題

如果表達式ngIf指令指的是獲得由(異步更新這個問題可能發生)調用從外部角度區內的未來。這不會導致角度變化檢測,所以您的視圖將不會更新,直到下一次更改檢測發生。您可以通過以下鏈接瞭解有關區域的更多信息並更改檢測結果:zoneschange detection

我在將Google登錄集成到我的組件時遇到此問題。 signInChangeListener由第三方谷歌圖書館稱爲每當或出用戶的跡象:

export class GoogleLoginService { 
    signedIn: boolean = false; 
    ... 
    signInChangeListener(isSignedIn) { 
     this.signedIn = isSignedIn; 
    } 
} 

在我的HTML我有:

<div *ngIf="signedIn"> ... </div> 

我有這樣的變化是由檢測更改我的代碼角:

import { Injectable, NgZone } from '@angular/core'; 

export class GoogleLoginService { 
    signedIn: boolean = false; 

    constructor(private ngZone: NgZone) { } 
    ... 
    signInChangeListener(isSignedIn) { 
     // Run the value change inside angular 
     this.ngZone.run(() => { 
     this.signedIn = isSignedIn; 
     }); 
    } 
}