javascript - ng-if 当 AngularJS 中的 $scope var 更改时不更新

标签 javascript angularjs

在我看来,我有这样的:

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

在我的 Controller 中,我有:

$scope.mapStatus = {};

然后是当满足某些条件(例如离线等)时更新 ng-if 使用的作用域变量的各种函数(例如:

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

我的问题是,尽管范围变量已正确更改(通过良好的 'ol console.log 和 Angular chrome 扩展进行确认),但 View 中的 ng-if 永远不会更新/添加/删除显示/删除 div。

我尝试过使用 $apply (尽管我对它的理解不是很好),例如:

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

但这会引发错误,例如错误:[$rootScope:inprog] $apply已经在进行中

感觉我错过了一些明显的东西:(

<小时/>

根据要求提供更多代码:

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

最佳答案

我不确定这是否能解决您的问题,但在您深入讨论之前,我建议您删除对 $scope 的引用并使用controllerAs。我见过很多实例,其中对直接添加到 $scope 的属性/方法的引用由于没有特殊原因而失败。我特别建议您:

  • 删除您注入(inject) $scope 的位置,
  • var ctrl=this 添加到 Controller 中的构造函数代码中,
  • 将 Controller 中对 $scope 的所有引用更改为 ctrl,
  • 将controllerAs vm添加到加载 Controller 的位置,
  • 将 View 中对 Controller 属性的所有引用更改为以 vm 为前缀。

您可能很幸运,这可能会解决您的问题,但无论哪种方式,这仍然是使用 Controller 的更好方法。 (如果您使用的是 Angular 1.5+,我真的建议您在走得太远之前将其重构为一个组件。)

关于javascript - ng-if 当 AngularJS 中的 $scope var 更改时不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44567677/

相关文章:

angularjs - Angular UI-Router 将根 url 发送到 404

javascript - 在javascript中读取文本文件的第一行

javascript - 找不到模块 : Error: Can't resolve './node_modules/react' in '/Users/<user-name>/Documents/gift-test/client'

javascript - 仅获取所选输入文件的名称

javascript - 在运行时确定元素通过 JavaScript 实现了哪些样式

javascript - 在 AngularJS 完成异步加载后向 DOM 添加内容

javascript - 是否有可能禁用 ionic 2 中的按钮?

javascript - 单击按钮时 JQuery 追加

javascript - 编辑电话号码时,光标跳到末尾

javascript - 在 AngularJS 中加载时隐藏模板