在AngularJS中的另一个方法中访问返回的范围方法变量

时间:2014-01-14 20:56:54

标签: angularjs angularjs-scope

我有一个带服务和控制器的Angular应用程序:

service.js

.factory('MyService', function ($http, $q) {
    var api_url = 'http://localhost/api/';

    var MyService = {

        list: function (items_url) {
            var defer = $q.defer();
            $http({method: 'GET', 
                url: api_url + items_url}).
                success(function (data, status, headers, config) {
                    defer.resolve(data);
                }).error(function (data, status, headers, config) {
                    defer.reject(status);
                });
            return defer.promise;
        },
        ...
   }
});

controller.js

.controller("ItemsCtrl", function ($scope, MyService) {

    $scope.getItems = function () {
        MyService.list('items/').then(function(data) {
            $scope.items = data;
        });
    };

    $scope.addItems = function () {
        $scope.getItems();

        // why is this undefined ??!!!
        console.log($scope.items); 
    };

问题是我想在$scope.getItems方法中调用$scope.addItems方法。我是否可能需要使用$scope.apply(),因为返回的值是一个承诺?

我认为我在这里展示的是普遍缺乏理解。

3 个答案:

答案 0 :(得分:3)

按照以下方式更改您的控制器:

.controller("ItemsCtrl", function ($scope, MyService) {

    $scope.getItems = function () {
        return MyService.list('items/').then(function(data) {
            $scope.items = data;
        });
    };

    $scope.addItems = function () {
        $scope.getItems().then(function() {

          // should be what you want this time
          console.log($scope.items); 

        });
    };

问题是当您致电$scope.getItems()时,尚未返回http响应,因此未填充$scope.items。您必须等待所有承诺决定访问items

答案 1 :(得分:0)

$scope.items未定义,因为$http异步通信。也就是说,当您调用$scope.addItems()时,它会创建并发送请求以检索您的项目列表,然后立即转到下一行代码,即将$scope.items记录到控制台。由于$scope.items中没有任何内容,因此您会得到一个未定义的值。

如果要对http调用返回的数据进行操作,则必须保证将填充数据。换句话说,您要在$scope.items块中调用要在.then()上执行的任何操作。

当您未在AngularJS上下文中执行时,使用

$scope.$apply()来强制AngularJS框架评估表达式。它对你没有帮助 - 你会得到一个“已经在进行中的$ digest”错误,或类似的东西。

试试这个:

.controller("ItemsCtrl", function ($scope, MyService) {

  $scope.getItems = function () {
    MyService.list('items/').then(function(data) {
      $scope.items = data;
      console.log($scope.items); 
    });
  };

  $scope.addItems = function () {
    $scope.getItems();
  };
});

答案 2 :(得分:0)

这是因为$scope.getItems是异步的。您的回调(通过那时添加)将在$scope.addItems执行后调用。