AngularJS - 范围变量未从方法更新

时间:2013-05-03 09:59:57

标签: angularjs

我是AngularJs的新手,我有这个问题,我不明白。我有两种方法。第一个从Web服务获取一些数据并放入范围中定义的变量中。但是当我想在第二种方法中使用该变量时,它是未定义的。有人可以帮我理解为什么会这样,并提供解决方案吗?

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

myApp.controller("myAppController",
function( $scope ) {
$scope.getAll = function(){
    $.ajax({
        type: "GET",
        dataType: "jsonp",
        contentType: "application/json; charset=utf-8",
        url: ..something...,
        success: function (parameters) {
            $scope.profiles = angular.copy(parameters);  <-- correct data is returned
            $scope.$apply();
        },
        error: function () {
            alert("Error calling the web service.");
        }
    });
}
$scope.getCategories = function(){
    var all = $scope.profiles;    <-- At this point profiles is empty
    ...
}
    $scope.getAll();
    $scope.getCategories();
}

4 个答案:

答案 0 :(得分:2)

当您致电getCategories()时,getAll()尚未完成,这就是配置文件为空的原因。有几种方法可以解决这个问题。最好的方法是使用内置$http服务的承诺。

如果您更喜欢使用jQuery,可以在profiles变量上添加观察程序,并且只有在填充后才会运行getCategories()

这样的事情应该有效:

$scope.getAll = function(){
    $.ajax({
        type: "GET",
        dataType: "jsonp",
        contentType: "application/json; charset=utf-8",
        url: ..something...,
        success: function (parameters) {
            $scope.profiles = angular.copy(parameters);  <-- correct data is returned
            $scope.$apply();
        },
        error: function () {
            alert("Error calling the web service.");
        }
    });
}

$scope.getCategories = function(){
    var all = $scope.profiles;

}

// Wait for the profiles to be loaded
$scope.watch('profiles', function() {
    $scope.getCategories();
}

$scope.getAll();

答案 1 :(得分:2)

使用$ http服务并承诺:

$scope.profiles = $http.jsonp(url).then(function(r){ return r.data; });
$scope.categories = $scope.profiles.then(function(profiles) {
  var params = { }; // build url params
  return $http.jsonp(url, { params: params }).then(function(r){ return r.data; });
});

答案 2 :(得分:1)

在调用getAll之前,无法保证getCategories已完成,因为它是异步请求。因此,如果您要依次调用getAllgetCategories,则应在getCategories的{​​{1}}回调中调用success。您还可以查看getAll以查找链接异步回调的更简洁方法(我假设您正在使用jQuery,因为您正在调用promises)。

$.ajax

(如果您正在使用jQuery承诺)

...
<snipped some code>

success: function(parameters) {
    // snipped more code
    $scope.getCategories();
}

两者都不是&#34; Angularish&#34;但是,您可能希望查看一些提供的服务,以便使用http / rest资源而不是使用jQuery。

答案 3 :(得分:1)

为什么你在角度使用jQuery ajax请求?如果你编写jQuery样式代码并将其包装成角度,那么你将会遇到糟糕的时间......

这是一个有角度的版本:

myApp.controller("myAppController",
function( $scope, $q, $http ) {

  $scope.getAll = function(){
    var deferred = $q.defer();
    $scope.profiles = deferred.promise;
    $http.jsonp('your url').then(function(data) {
      deferred.resolve(data);
    }); 
  });

  $scope.getCategories = function(){
    $q.when($scope.profiles).then(function(profiles) {  
       ... <-- At this point profiles is populated
    });    
  }

  $scope.getAll();
  $scope.getCategories();
}