angularjs获取json要调用2次才能获取到数据

BenChao 发布于 2016/06/13 11:13
阅读 1K+
收藏 0

在使用angularjs做一个web应用,页面初始化的时候就加载数据,但是controller里面的$scope.grades第一次都是获取不到数据,要使用一个按钮触发$scope.initData()才能获取到数据。 这是为什么呢?请大神指点

var app = angular.module('easylearn', ['ngResource']);

app.constant("URL", {
    "add": "/grade/add",
    "remove": "/grade/remove",
    'update':"/grade/update",
    'list':"/grade/list",
    'count':'/grade/count'
})
    
.factory('GradeFactory', function($resource, $rootScope, URL) {
    var service = {};
    var grade = {};

    service.findAll = function(){
        var resource = $resource(URL.list, {}, {
            query:{
                method: 'post',
                params:{},
                timeout: 20000
            }
        });
        resource.query({}, function(r){
            grade = r.grades;
        });

        return grade;
    }

    return service;
})
    
.controller('GradeCtrl', function($scope, $rootScope, URL, GradeFactory) {
    $scope.initData=function(){
        $scope.grades = GradeFactory.findAll();
        console.log($scope.grades);
    };

    $scope.initData();

});



加载中
0
wuyiw
wuyiw
估计因为query是异步的. 返回的grade自然也就是空的{}了.第二次点击其实返回的是第一次的获取结果.
0
BenChao
BenChao

引用来自“wuyiw”的评论

估计因为query是异步的. 返回的grade自然也就是空的{}了.第二次点击其实返回的是第一次的获取结果.
那该怎么破? 不写factory,直接在controller里面获取数据然后绑定是没有问题的
0
wuyiw
wuyiw

引用来自“wuyiw”的评论

估计因为query是异步的. 返回的grade自然也就是空的{}了.第二次点击其实返回的是第一次的获取结果.

引用来自“BenChao”的评论

那该怎么破? 不写factory,直接在controller里面获取数据然后绑定是没有问题的
对angular不熟, $resource有个$promise是吧, 试试返回它而不是grade. 然后在$promise.then()中处理数据.
BenChao
BenChao
谢谢!
0
Isronik
Isronik

你这个说来真是有点混乱。。。。

首先说为何没有返回。resoure.query。按官方说明,是会立即返回的,但是一开始是不可能这么快取到值的,所以返回的是空的。(It is important to realize that invoking a $resource object method immediately returns an empty reference (object or array depending on isArray). )所以你的$scope.grades=GradeFactory.findAll,瞬间返回空的。然后等他取到值之后呢,他会把这个值再补回来。( Once the data is returned from the server the existing reference is populated with the actual data. )。但是后来即使resrouce.query里返回有值到grade里的了,因为你的findAll已经return,所以findAll里面的变量grade和返回的grade已经没有关联了。

再说怎么做比较好。通常来说,你的factory只需要定义$resource的实例就好了。也就是这是一个没有状态的,纯是接口的东东。
然后像findAll这样的,要写在controller里。下面给你一个类似的demo.

service.js文件

(function(){
    var service = angular.module('garage.service', [
        'ngResource'
    ]);
    service.factory('Garage', ['$resource', function($resource){
        return $resource('someURL/garages', {}, {
            //这没有写内容,因为默认就继承了query,get,delete,save,remove等
        });
    }]);


})();



controller.js文件
(function () {
    var module = angular.module('garage.controller', [
        'garage.service'
    ]);

    module.controller('garage.MainCtrl', ['$scope', 'Garage', 
        function ($scope, Garage) {

            function load(){
                Garage.get(null, function (res, resHeader) {
                    $scope.garages = res.response.datas;
                });
            }

            load();
......



看load里的$scope.garages,这里一开始也是空的。但是由于$resource后来会返回值,所以界面等收到了值后,便会自动显示出来了。

0
BenChao
BenChao

引用来自“Isronik”的评论

你这个说来真是有点混乱。。。。

首先说为何没有返回。resoure.query。按官方说明,是会立即返回的,但是一开始是不可能这么快取到值的,所以返回的是空的。(It is important to realize that invoking a $resource object method immediately returns an empty reference (object or array depending on isArray). )所以你的$scope.grades=GradeFactory.findAll,瞬间返回空的。然后等他取到值之后呢,他会把这个值再补回来。( Once the data is returned from the server the existing reference is populated with the actual data. )。但是后来即使resrouce.query里返回有值到grade里的了,因为你的findAll已经return,所以findAll里面的变量grade和返回的grade已经没有关联了。

再说怎么做比较好。通常来说,你的factory只需要定义$resource的实例就好了。也就是这是一个没有状态的,纯是接口的东东。
然后像findAll这样的,要写在controller里。下面给你一个类似的demo.

service.js文件

(function(){
    var service = angular.module('garage.service', [
        'ngResource'
    ]);
    service.factory('Garage', ['$resource', function($resource){
        return $resource('someURL/garages', {}, {
            //这没有写内容,因为默认就继承了query,get,delete,save,remove等
        });
    }]);


})();



controller.js文件
(function () {
    var module = angular.module('garage.controller', [
        'garage.service'
    ]);

    module.controller('garage.MainCtrl', ['$scope', 'Garage', 
        function ($scope, Garage) {

            function load(){
                Garage.get(null, function (res, resHeader) {
                    $scope.garages = res.response.datas;
                });
            }

            load();
......



看load里的$scope.garages,这里一开始也是空的。但是由于$resource后来会返回值,所以界面等收到了值后,便会自动显示出来了。

谢谢! 按照您的方法,问题已经解决了! service里面返回$resource ,然后在controller里面处理
Isronik
Isronik
记得引用我的答案咧~~好加点技能分~~~:)
返回顶部
顶部