繁体   English   中英

在工厂的GET请求之后,AngularJs $ scope不会更新

[英]AngularJs $scope doesn't update after a GET request on a factory

我一直在尝试AngularJS进行实验项目,我也遇到了这个问题。 在我的HTML中,我想显示一个项目列表

的index.html

<h1>Some list</h1>
<div ng-controller="datlist">
    <div ng-repeat="item in items">
        <div>Item description: {{item.description}}</div>
        <div>Item name: {{item.name}}</div>
    </div>
</div>

起初我使用一个简单的控制器来获取信息并使用以下更新视图:

controllers.js(原创)

function datlist($scope,$http){
$http({method: 'GET', url: 'http://localhost:61686/getdatlist?format=json', headers: {'Access-Control-Allow-Origin': 'localhost:*'}}).
    success(function(data, status, headers, config) {
        $scope.items=data.itemsToReturn;
        console.log(data);
}).
error(function(data, status, headers, config) {
    console.log("fail");
});

}

这工作得很好,我可以获得项目列表。 同时,通过更改我的结构以使用工厂发出相同的请求并将其绑定到$ scope.items它不起作用。 我尝试了很多$ watch的变种,但是我无法更新$ scope.items。 我发现了一些关于$ apply的内容,但我真的无法理解如何使用它。

controllers.js(新的)

var datModule = angular.module('datModule',[]);
datModule.controller('datlist', function ($scope, datfactory){
    $scope.items = datfactory.getlist();
    $scope.$watch($scope.items, $scope.items = datfactory.getlist());
});
datModule.factory('datfactory', function ($http){
    var factory = {};
    factory.getlist = function(){
        $http({method: 'GET', url: 'http://localhost:61686/getdatlist?format=json', headers: {'Access-Control-Allow-Origin': 'localhost:*'}}).
        success(function(data, status, headers, config) {
            console.log(data.itemsToReturn); //I get the correct items, all seems ok here
            return data.itemsToReturn;
        }).
        error(function(data, status, headers, config) {
            console.log("fail");
        });

    }
    return factory;
});

任何有关这方面的想法都会很棒。 PS:我发现很多帖子都在谈论这个问题但是没有一个能帮我找到完整的解决方案。

谢谢

使用手表有点难看。

试试这个:

datModule.factory('datfactory', function ($http, $q){

    this.getlist = function(){            
        return $http.get('http://localhost:61686/getdatlist?format=json',{'Access-Control-Allow-Origin': 'localhost:*'})
            .then(function(response) {
              console.log(response); //I get the correct items, all seems ok here
              return response.data.itemsToReturn;
            });            
    }
    return this;
});

datModule.controller('datlist', function ($scope, datfactory){
    datfactory.getlist()
      .then(function(arrItems){
         $scope.items = arrItems;
       });
});

这就是你如何使用promise来处理异步问题。

更新(2015年1月15日):现在更时尚!

该问题与范围摘要周期无关。 您正试图直接从回调内部返回,这不是异步的。

我建议您使用promise,或直接返回http promise。

var factory = {};
factory.getlist = function(){
    return $http({method: 'GET', url: 'http://localhost:61686/getdatlist?format=json', headers: {'Access-Control-Allow-Origin': 'localhost:*'}});

}
return factory;

直接返回promise,并在factory.getlist().success()处理成功/失败factory.getlist().success()

或者,如果要围绕请求包含其他逻辑,请使用您自己的承诺。

var datModule = angular.module('datModule',[]);

datModule.controller('datlist', function ($scope, datfactory){
    $scope.items = [];
    datfactory.getlist().then(function(data) { $scope.items = data });
});

datModule.factory('datfactory', function ($http, $q){
    var factory = {};
    factory.getlist = function(){
        var defer = $q.defer();
        $http({method: 'GET', url: 'http://localhost:61686/getdatlist?format=json', headers: {'Access-Control-Allow-Origin': 'localhost:*'}}).
        success(function(data) {
            // alter data if needed
            defer.resolve(data.itemsToReturn);
        }).
        error(function(data, status, headers, config) {
            defer.reject();
        });
        return defer.promise;
    }
    return factory;
});

它看起来很完美但你可以使用这样的$apply

datModule.controller('datlist', function ($scope, datfactory){
    $scope.$apply(function() {
        $scope.items = datfactory.getlist();
    });
});

尝试初始化$scope.items = []; 在控制器上,在调用$ http之前

我希望它对你有所帮助。

我认为这个问题的另一个优雅的解决方案可能是 - 如果您使用其中一个路由库,在我的情况下它是UI路由器,但也可能是ngRoute,使您的控制器依赖于承诺的响应,例如。 将一个resolve属性添加到适当的状态/路由,这个状态/路由不会让控制器加载,直到promise被解决并且数据准备就绪 ,所以在你的配置中:

.state('datpage', {
      url: '/datpage',
      controller: 'DatpageController',
      resolve:{
        datData: function (datfactory) {
            return datDataService.getData("datDataParam");
        }]
      },
      templateUrl: 'views/datpage.html'
    })

并在控制器中注入datData依赖项,您可以将其直接应用于$ scope:

.controller('DatpageController', function ($scope,datData) {
$scope.datPageData = datData; ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM