AngularJS NG重复与服务数据 [英] AngularJS ng-repeat with data from service

查看:164
本文介绍了AngularJS NG重复与服务数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

原来在我的应用程序,我创建了控制器,具有非常基本的$ HTTP调用从URL($ routeParams)获得一个物体的ID来获得资源。吴重复正确显示的结果。

Originally in my app, I created controllers with very basic $http calls to get a resource by getting the ID of an object from the url ($routeParams). Ng-repeat display the results correctly.

不过,我注意到在后面的视图(不同的控制器)刷新消灭了数据,并打破了网页。所以,我创建的服务功能在多个控制器中使用,检查数据是否有可用和反应如下:

However, I noticed refreshing in a later view (different controller) wiped out the data and broke the page. So, I created a function on the service to be used in multiple controllers, to check whether the data has is available and to react as follows:

1)如果资源被定义,其返回(无API调用)
2)如果没有定义的资源,您可以通过URL中的ID和从API得到它
3)如果资源没有被定义&放大器;你不能得到的ID,就返回false。

1) If the resource is defined, return it (no API call) 2) If the resource is not defined, get the id from the url and get it from the API 3) If the resource is not defined & you can't get the ID, just return false.

不过,这打破了code:服务之前呈现模板返回的数据,和NG重复没有更新。在code是这样的:

However, this broke the code: the template rendered before the service returned the data, and ng-repeat did not update. The code looks like this:

angular.module('myApp', ['ngCookies'])
    .config(...)
    .service('myService', ['$cookies', '$http', function($cookies, $http) {
        myData = {};

        return {
            getData:function(dataID) {
                if(myData.name) {return myData);
                else if (dataID && dataID !== '') {
                    $http.get('/api/data/' + dataID)
                        .success(function(data) {
                            myData = data.object;
                            $cookies.dataID = data.object.id;
                            return myData;
                        }
                }
                else { return false; }
            }
        }
    }]);

function myCtrl($scope, $http, $routeParams, myService) {
    $scope.data = myService.getData($routeParams.dataID);

    ...
}

和这里的模板。这是玉,这意味着而非尖括号,你只需列出括号后与右后括号中的参数元素和内容。

And here's the template. It's in jade, which means rather than angle brackets, you just list the element with parameters in parenthesis right after, and content after the parenthesis.

h2 My heading
ul
    li(ng-repeat='option in data')
        a(href="#", ng-click='someFuncInCtrl(option.name)')  {{ option.name }}

在控制器做了$ http.get本身,NG-重复工作得很好,因为$范围是在.success回调更新。现在,有一个轻微的延迟后返回数据的服务,$ scope.data只是不确定,纳克重复列表是空的。

When the controller did the $http.get itself, the ng-repeat worked fine because the $scope was updated in the ".success" callback. Now that there's a service that returns the data after a slight delay, "$scope.data" is just undefined, the ng-repeat list is empty.

我用的console.log回归之前检查MYDATA的权利返回myData的,而myData的工作,它只是没有及时回来,不管出于什么原因,只要$范围并获得名单没有更新数据。

I used a console.log to check myData right before return "return myData", and the myData is working, it just isn't returned in time, and for whatever reason the list is not updating whenever $scope does get the data.

我看了一个使用$ routeProvider的决心......但,使得从URL有挑战性获取ID,如决心对象似乎不能够访问$ routeParams。我知道,$范围。$应用是应该帮助,当它受到外界的功能改变更新的范围......但我不知道在哪里把它。在<一个href=\"http://stackoverflow.com/questions/13163227/angularjs-ngrepeat-not-updating-display-properly\">most类似的问题在的SO未使用的服务。

I looked a using $routeProvider's resolve... but that makes getting the ID from the url challenging, as the resolve object doesn't seem to have access to $routeParams. I know that $scope.$apply is supposed to help update the scope when it's altered by outside functions... but I have no clue where to put it. The most similar problem on SO didn't use a service.

我试过:

$scope.$apply($scope.data = myService.getData($routeParams.dataID));

$scope.$apply(function() {
    $scope.data = myService($routeParams.dataID);
});

这两次我只得到了错误:$进展已经消化

Both times I only got Error: $digest already in progress.

推荐答案

问题是你与服务交互的方式。由于您的的getData 功能便可返回的同步和/或异步的信息,你不能只是使用普通的收益(S)。

The problem is on the way you interact with the service. Since your getData function can return both synchronous and/or asynchronous information, you can't just use normal return(s).

$http.get('/api/data/' + dataID)
    .success(function(data) {
        myData = data.object;
        $cookies.dataID = data.object.id;
        return myData;
    });

收益在上面的代码将不会返回从的getData什么,因为它将对上下文中执行在 $ http.get 成功回调(而不是在的getData 调用堆栈)。

The return on the above snippet will not return anything from getData because it will be executed on the context of the $http.get success callback (and not on the getData call stack).

有关处理同步和异步服务请求的最佳方法是使用承诺

The best approach for handling sync and async service requests is to use promises.

的getData 函数应该是这个样子:

Your getData function should look something like this:

getData:function(dataID) {
    var deferred = $q.defer();
    if(myData.name) {
       deferred.resolve(myData);
    } else if (dataID && dataID !== '') {
        $http.get('/api/data/' + dataID)
            .success(function(data) {
                 myData = data.object;
                 $cookies.dataID = data.object.id;
                 deferred.resolve(myData);
                 // update angular's scopes
                 $rootScope.$$phase || $rootScope.$apply();
             });
    } else { 
       deferred.reject();
    }

    return deferred.promise;
}

请注意:您需要注入 $ rootScope 您的服务

Note: You need to inject the $rootScope on your service.

和控制器上:

function myCtrl($scope, $http, $routeParams, myService) {
    myService.getData($routeParams.dataID).then(function(data) {
        // request was successful
        $scope.data = data;        
    }, function() {
        // request failed (same as your 'return false')
        $scope.data = undefined;
    });
}

这篇关于AngularJS NG重复与服务数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆