angularjs

时间:2015-10-01 13:52:15

标签: javascript angularjs asynchronous

我对角度异步函数有几个问题。我希望我的服务功能能够通过使用$ http返回我获得的数据并在另一个函数中使用该数据。让我演示一下当前的代码:

dashboard.servicesModule.service('SubscriptionService', function ($http, $q) {

    this.getImportantData= function (param1, param2) {

        var url = "my/url/with/parameters?param1=param1&param2=param2";     

        $http.get(url).then(function(response){         
            console.log("response");
            console.log(response.data); // < --- this actually shows the data i need!!          
            return response.data.vsyData; <--- however, this returns undefined
        }, function(error){
            // some error thingy just in case
        });

    };

    this.getSomeFunctionality = function(param1, param2, param3){
        var importantdata= this.getImportantData(param1, param2);

        // do some filtering on the data with the purpose of returning only what i need

        console.log(importantdata); <--- undefined

    };

    this.getEvenMoreFunctionality = function(param1, param2, param3){
        var importantdata= this.getImportantData(param1, param2);

        // reusing getImportantData again! 

        console.log(importantdata); <--- undefined

    };
});

所以我一直在尝试各种各样的事情(比如thisthis)以及我自己的一些发明。但它开始似乎没有办法在其自己的回调中使用来自$ http.get的数据。因为我需要在我的控制器中使用endresult,所以似乎没有其他方法可以在我的控制器中执行 $ http.get(url).success(...这里有一些逻辑)那里的过滤和其他操纵。

但是,我读了here并引用:

  

我们的控制器几乎完全不了解数据的方式   检索和发送,应该只关心一般   向服务发送数据和从服务中检索数据的操作。

我将此解释如下:我的控制器应该向服务询问我需要的数据,服务应该确保它以正确的形式提供数据。

最重要的问题是:如何让上面的代码做它需要做的事情或者那是不可能的?

我是否应该在控制器中执行业务逻辑?因为here, in the angular docs我基本上读到你应该在你的控制器中做业务逻辑,但不要过滤......

它可能很明显,但是......我是一个有角度的新手:-)。 谢谢!

3 个答案:

答案 0 :(得分:4)

试试这个:

this.getImportantData= function (param1, param2) {
    var url = "my/url/with/parameters?param1=param1&param2=param2";     

    return $http.get(url);
};

this.getSomeFunctionality = function(param1, param2, param3){
    this.getImportantData(param1, param2)
    .then(function(response){         
        console.log(response.data.vsyData);
    }, function(error){
        // some error thingy just in case
    });
};

this.getEvenMoreFunctionality = function(param1, param2, param3){
    this.getImportantData(param1, param2)
    .then(function(response){         
        console.log(response.data.vsyData);
    }, function(error){
        // some error thingy just in case
    });
};

您无法从具有异步调用的方法获取数据。您可以返回承诺,然后您可以从承诺中获取数据。

答案 1 :(得分:2)

对于同步请求,您无法使用imediate return语句,因此主javascript线程不会等待请求解析。我真的建议使用$q API,这是Kris Kowal的Q承诺/延期系统的角度实现。

function getSomething(){
    var deferred = $q.defer();
    $http.get('foo/bar')
        .success(function(data){
            $deferred.resolve(data);
        });
    return deferred.promise();
}

getSomething().then(function(data){
    console.log(data);
});

或者您可以直接返回$http承诺。如果您想从控制器中删除.then(),可以将$routeProvider与支持resolve承诺的$q选项一起使用,并创建自行解析数据的路由,以便你只需将它们注入控制器,不受$q程序的限制。

更新1 - 解决路线中的依赖关系的实际示例

$routeProvider.when('/items/list', {
    templateUrl: '/templates/item/list',
    controller: 'ListItemsCtrl',
    resolve: {
      items: function(ItemsService) {
        return ItemsService.getItems(); // getItems returns a promise like 'return $http.get('/items');'
      }
    }
  });

//controller
function ListItemsCtrl($scope, items){
    //do something with your items
}

答案 2 :(得分:0)

function getSomething(){
var deferred = $q.defer();
$http.get('foo/bar')
    .success(function(data){
        $deferred.resolve(data);
    });
return deferred.promise();
}
  getSomething().then(function(data){
   console.log(data);
});