AngularJS - ng-bind不更新

Ale*_*ans 17 javascript angularjs

我有一个控制器,它具有从API获取一些警报的功能,并更新我的站点前端的计数,该计数绑定到警报.

不幸的是,ng-bind我正在使用的属性似乎并没有实时更新计数,即使一个简单console.log()的告诉我实际警报计数正在控制器中更新.

前端

<div class="modeSelector modeSelector_oneUp" data-ng-controller="MyLivestockController as vm">
    <a class="modeSelector-mode" data-ui-sref="my-livestock">
        <div class="modeSelector-type">Alerts</div>

        <img class="modeSelector-icon" src="/inc/img/_icons/envelope-black.svg" onerror="this.src=envelope-black.png" />

        <span data-ng-bind="vm.alertCount"></span>
    </a>
</div>
Run Code Online (Sandbox Code Playgroud)

调节器

(function() {

  'use strict';

  function MyLivestockController(userService) {

    var vm = this;

    vm.myLivestockNotification = {
      isLoading: true,
      hasError: false
    };

    vm.alertsNotification = {
      isLoading: true,
      hasError: false,
      hasData: false
    };

    vm.deleteAlert = function(id) {

      vm.currentAlert = void 0;
      vm.alertsNotification.isLoading = true;

      userService.deleteAlert(vm.user.id, id).then(function() {

        // Remove the alert from our Array
        vm.alerts = vm.alerts.filter(function(alert) {
          return alert.id !== id;
        });

        // Refresh the alert count for the user
        vm.getAlerts(vm.user.id);

        vm.alertsNotification.isLoading = false;
        vm.alertsNotification.hasError = false;
      }, function() {
        vm.alertsNotification.hasError = true;
      });
    };

     vm.getAlerts = function(id) {
        userService.getAlerts(id).then(function(alertData) {
          vm.alertCount = alertData.length;

          if (vm.alertCount > 0) {
            vm.alertsNotification.hasData = true;
          } else {
            vm.alertsNotification.hasData = false;
          }

          vm.alerts = alertData;

          vm.alertsNotification.isLoading = false;
          vm.alertsNotification.hasError = false;
        }, function() {
          vm.alertsNotification.hasError = true;
        });
    };

    // Init
    (function() {
      userService.getCurrentUser().then(function(data) {
        vm.myLivestockNotification.hasError = false;
        vm.myLivestockNotification.isLoading = false;

        vm.user = data;

        // Get alert count for the user
        vm.getAlerts(vm.user.id);
      }, function() {
        vm.myLivestockNotification.hasError = true;
      });
    })();
  }

  angular
    .module('abp')
    .controller('MyLivestockController', MyLivestockController);

})();
Run Code Online (Sandbox Code Playgroud)

服务

(function() {

  'use strict';

  function userService($q, $sessionStorage, $localStorage, $filter, user) {

    var service = this;

    service.getAlerts = function(id) {
      var deferred = $q.defer();

      user.alerts({ userID: id }, function(response) {
        if (response.hasOwnProperty('data')) {

          // Convert dates to valid Date
          angular.forEach(response.data, function(alert) {
            /* jshint camelcase: false */
            if (alert.created_at) {
              alert.created_at = $filter('abpDate')(alert.created_at);
            /* jshint camelcase: true */
            }
          });

          deferred.resolve(response.data);
        }
        else {
          deferred.reject('DATA ERROR');
        }
      }, function(e) {
        deferred.reject(e);
      });

      return deferred.promise;
    };

  angular
    .module('abp')
    .service('userService', userService);

})();
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,getAlerts()每次使用该deleteAlert()功能删除警报时,我都会调用我的函数,但是<span data-ng-bind="vm.alertCount"></span>在刷新页面后,前端只会更新,我希望它能在现场更新.

Dan*_*zyk 26

您的绑定未更新,因为您更改了角度应用程序的摘要周期之外的alertCount值.刷新应用程序时,摘要会运行,因此您的值会更新.在$ scope.apply()中包装变量的更新,如下所示:

$scope.$apply(function(){
    vm.alertCount = alertData.length;
});
Run Code Online (Sandbox Code Playgroud)

这将强制摘要并更新实时值.
如果您有更多的值在摘要之外更新(任何回调,承诺等),您可以通过调用强制摘要周期:

$scope.$apply();
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你.

编辑-----
鉴于你的完整代码更新,我发现你没有在控制器的任何地方注入范围,我写的控制器通常是这样开始的:

(function () {

var app = angular.module('mainModule');

app.controller('myController', ['$scope', '$myService', function ($scope, $myService) {

    //logic
}]);
}());
Run Code Online (Sandbox Code Playgroud)

编辑-----
这是我对你的代码的快速进展:

(function() {
'use strict';


var app = angular.module('abp');

app.controller('MyLivestockController', ['$scope', 'userService', function($scope, userService) {

    var vm = {};
    $scope.vm = vm;

    vm.myLivestockNotification = {
        isLoading: true,
        hasError: false
    };

    vm.alertsNotification = {
        isLoading: true,
        hasError: false,
        hasData: false
    };

    vm.deleteAlert = function(id) {

        vm.currentAlert = void 0;
        vm.alertsNotification.isLoading = true;

        userService.deleteAlert(vm.user.id, id).then(function() {

            // Remove the alert from our Array
            vm.alerts = vm.alerts.filter(function(alert) {
                return alert.id !== id;
            });

            // Refresh the alert count for the user
            vm.getAlerts(vm.user.id);

            vm.alertsNotification.isLoading = false;
            vm.alertsNotification.hasError = false;
        }, function() {
            vm.alertsNotification.hasError = true;
        });
    };

    vm.getAlerts = function(id) {
        userService.getAlerts(id).then(function(alertData) {
            vm.alertCount = alertData.length;

            if (vm.alertCount > 0) {
                vm.alertsNotification.hasData = true;
            } else {
                vm.alertsNotification.hasData = false;
            }

            vm.alerts = alertData;

            vm.alertsNotification.isLoading = false;
            vm.alertsNotification.hasError = false;

            //important, this is promise so we have to apply the scope to update view
            $scope.$apply();
        }, function() {
            vm.alertsNotification.hasError = true;
        });
    };

    // Init
    (function() {
        userService.getCurrentUser().then(function(data) {
            vm.myLivestockNotification.hasError = false;
            vm.myLivestockNotification.isLoading = false;

            vm.user = data;

            // Get alert count for the user
            vm.getAlerts(vm.user.id);
        }, function() {
            vm.myLivestockNotification.hasError = true;
        });
    })();
}]);

})();
Run Code Online (Sandbox Code Playgroud)

一般的想法是:

  1. 你创建一个应用程序(angular.module)
  2. 你在这个应用程序中创建一个控制器,注入$ scope
  3. 要在视图上更新的任何值,请添加到$ scope
  4. 如果你在回调,事件或承诺中有任何$ scope更新,你将它们包装在(或跟随)$ scope.$ apply call

我认为这对你有用:)