2017-06-15 56 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; 
     }); 
    } 
}