【问题标题】:When is $scope.$apply necessary for dealing with objects/arrays with Angular?什么时候需要 $scope.$apply 来使用 Angular 处理对象/数组?
【发布时间】:2014-06-23 07:39:11
【问题描述】:

我正在使用 Soundcloud JS SDK 将我的 Soundcloud 收藏夹带入一个简单的 Angular 应用程序中。

在我使用$scope.$apply 之前,我无法正确导入用户收藏夹。

function TopListCtrl($scope, $http, $modal) {
  $scope.getData = function(sc_user) {
     SC.get('/users/'+ sc_user +'/favorites', {limit: 200}, function(tracks){
     $scope.$apply(function() {
  if (Object.getOwnPropertyNames(tracks).length > 1) {
      $scope.likes = tracks;
      $scope.sortField = 'like.favoritings_count';
      $scope.reverse = true;
      $scope.sc_user = sc_user;
     } 
  else {
      alert("That user has 0 Soundcloud likes. So sad...")
     }
  }).error(function (data, status, headers, config) {          
             alert("Something went awry with that request. Double check that's a real Soundcloud username");         

        })
        }); 
  }

如果你不使用 $scope.apply,它就不起作用(并且说 SC.get not defined)。

我想更好地理解为什么$scope.$apply 是必要的。我问这个是因为当我只是使用http api时,我不需要它。

function TopListCtrl($scope, $http, $modal) {
  $scope.getData = function(sc_user) {
     var url = 'http://api.soundcloud.com/users/'+ sc_user +'/favorites.json?client_id=0553ef1b721e4783feda4f4fe6611d04&limit=200&linked_partitioning=1&callback=JSON_CALLBACK';
    $http.jsonp(url).success(function(data) {
     if (Object.keys(data.collection).length > 0) {
      $scope.likes = data;
      $scope.sortField = 'like.favoritings_count';
      $scope.reverse = true;
      $scope.sc_user = sc_user;
     } 
    else {
      alert("That user has 0 Soundcloud likes. So sad...")
     }
  }).error(function (data, status, headers, config) {          
             alert("Something went awry with that request. Double check that's a real Soundcloud username");         
        });
  }

【问题讨论】:

  • 相当简单...您正在使用代码更新不属于角度的范围,因此它不知道运行摘要循环

标签: angularjs angularjs-scope soundcloud


【解决方案1】:

通常 Angular 知道正在执行的代码,因为您是提供函数回调的人,但实际上是 Angular 调用它们。在 Angular 调用一个函数之后,它会在稍后的某个时间调用 $apply 来触发一个 $digest 循环。

如果您不知道 $digest 循环是什么,那么这个概念很简单。在 $digest 阶段,Angular 将对使用 $watch 处理程序设置的每个范围变量进行脏检查,并检查它是否已更改;如果它有 angular 将调用其相应的 $watch 处理程序来更新视图。

回到最初的问题——当 Angular 知道你的代码时,它会为你触发一个 $digest 循环——所以不需要显式调用 $apply。如果您处理 jquery 事件,那就是另一回事了。 Angular 不知道可能需要 $digest - 它怎么可能?所以需要 $apply 来手动触发 $digest。

【讨论】:

    【解决方案2】:

    我知道您已经收到对您问题的正确答复。我想我还要提一下,使用 $http 向 Soundcloud API 发出请求并不难,因此您不需要使用 $scope.$apply。这是我的:

      var request = function(method, path, params, callback) {
        params.client_id = sc.soundcloud.client_id;
        params.oauth_token = sc.soundcloud.access_token;
    
        $http({
          method: method,
          url: sc.soundcloud.api.host + path,
          params: params
        })
        .success(callback);
      };
    
        get: function(path, params, callback) {
          request('GET', path, params, callback);
        },
    
        put: function(path, params, callback) {
          request('PUT', path, params, callback);
        },
    
        post: function(path, params, callback) {
          request('POST', path, params, callback);
        },
    
        delete: function(path, params, callback) {
          request('DELETE', path, params, callback);
        }
    

    【讨论】:

      【解决方案3】:

      Pixelbits 的回答和an article by Jim Hoskins on $scope.$apply 帮助我更好地理解了这一点。这是我最初的问题的关键点:

      那么,什么时候需要调用 $apply()?很少,实际上。 AngularJS 实际上在 $apply 中调用了几乎所有的代码 称呼。 ng-click、控制器初始化、$http 回调等事件 都包含在 $scope.$apply() 中。所以你不需要调用它 你自己,事实上你做不到。在 $apply 中调用 $apply 会抛出 一个错误。

      如果您要在新的回合中运行代码,则确实需要使用它。和 仅当该回合不是从 AngularJS 中的方法创建时 库。 在这个新回合中,您应该将代码包装在 $scope.$apply() (强调我的)

      我在转弯时仍然很模糊,但我知道关键点是该方法(在我的情况下为 SC.get)不是 AngularJS 库的一部分,因此我需要使用 $apply

      (至少我想我明白了)

      【讨论】:

        猜你喜欢
        • 2015-07-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-05
        相关资源
        最近更新 更多