AngularJS - 在http get调用后数组没有更新 - 没有使用$ scope的解决方案?

时间:2015-04-27 01:09:54

标签: javascript angularjs angularjs-scope angularjs-ng-repeat angularjs-resource

假设我们有以下资源(使用ngResource模块),它返回一个JSON结果数组:

app.factory('myApi', function($resource) {
    return $resource('/myApi/:param')
    // returns an array of json objects
});

以下主控制器:

app.controller('mainController', function(myApi) {
    var results = []
    var _init = function() {
        myApi.get({param: 1234}, function(data) {
            results = data.results
        });
    }

    _init();

    return {
        results: results
    }
});

我想对结果进行ng-repeat。

<body ng-controller="mainController as main">
    <p ng-repeat="r in main.results">{{r.myResult}}</p>
</body>

我已确认资源正在返回正确的结果。但是,使用上面的模板,没有任何内容。

我试图在不使用$ scope并使用“Controller as”语法的情况下完成此操作。我还试图通过在控制器对象中不使用大量“this .___”来保持代码清洁和可维护(因此在控制器定义的末尾返回一个对象)。

解决这个问题的最简洁方法是什么?我见过大量使用$ scope的解决方案,但我不想再回到使用该对象。

2 个答案:

答案 0 :(得分:1)

您的示例有几个问题:

  1. 首先,当您在init的回调中设置results时,控制器的results字段不会引用该新数组。由于您没有使用Angular的$scope,因此您需要手动维护控制器的当前状态。
  2. 其次,由于您的回调是异步触发的,因此它不在当前的摘要循环中。因此,您需要在更新数据时手动强制摘要。
  3. 以下示例修复了控制器的两个问题:

    app.controller('mainController', function($scope, myApi) {
        // Create our non-angular state/scope to return upfront so
        // we can modify its "results" when we get our data back.
        var _ctrlState = {
            results: null
        };
    
        var _init = function() {
            myApi.get({param: 1234}, function(data) {
                // Update the results field on our controller's state
                // object and force a scope digest.
                _ctrlState.results = data.results;
                $scope.$digest();
            });
        }    
        _init();
    
        return _ctrlState;
    });
    

    这是一个工作小提琴(注意,它有一个假的myApi,返回数据以适合您的示例模板):http://jsfiddle.net/os1p0w64/

答案 1 :(得分:1)

我能够通过将对当前范围的引用保存到变量“vm”来解决问题:

app.controller('mainController', function(myApi) {
    var vm = this
    var results = []
    var _init = function() {
        myApi.get({param: 1234}, function(data) {
            vm.results = data.results
        });
    }

    _init();

    return {
        results: results
    }
});

因此,控制器范围中的“结果”对象将使用资源调用的结果进行更新。