【问题标题】:Passing data from ngRoute resolve to controller将数据从 ngRoute 解析传递给控制器
【发布时间】:2016-08-15 09:26:42
【问题描述】:

我有一个使用 ngRoute 生成 SPA 的应用程序。在完成从数据库中获取数据之前,我不想加载视图。以下方法有效,但我无法将返回数据传递给我的控制器。

角度服务:

angular.module('routeService',[])

.factory('dataFetch', function($http, $q){

var deferred = $q.defer();
var factory = {}

factory.getProposals = function(){


    return $http.get('urlHere')
        .then(function(response){
            //promise is fulfilled
            deferred.resolve(response.data);

            console.log("readched the bio service!" + response.data);

            //promise is returned
           // return deferred.promise;
            return response.data;

        }, function(response){
            deferred.reject(response);

            //promise is returned
            return deferred.promise;
        });};


      return factory;

   });

角度控制器:

var login = angular.module('login', ['ngRoute', 'routeService'])

 // configure our routes
login.config(function($routeProvider,$locationProvider) {
    $routeProvider

        // route for the home page

        .when('/', {
            templateUrl: '/overview.html',
            controller: 'login',
            resolve: {
                myDta: function(dataFetch){
                    return dataFetch.getProposals();
                }
            }

        })

});

login.controller('login', function($scope, myDta){

   $scope.prop = myDta

}) 

我收到以下错误:

Unknown provider: myDtaProvider <- myDta <- login

【问题讨论】:

  • 除了一些不良的承诺实践之外,我认为您的代码没有真正的问题。您是否在 index.html 文件中包含了 routeService.js
  • @MuliYulzary 你能解释一下不好的做法吗?

标签: javascript html angularjs angular-services ngroute


【解决方案1】:

错误使用ng-controller='login'

我收到以下错误:

Unknown provider: myDtaProvider <- myDta <- login

错误消息意味着login 控制器正在从某处的ng-controller 指令实例化。当ngRoute 服务实例化一个控制器时,它将解析为一个本地ng-controller 指令无权访问路由器的解析。

来自另一个 StackOverflow 答案:1

ngRoute 支持将解析变量注入控制器,这对于应用的横切关注点非常有用,例如应用的身份验证或配置。

缺点是控制器只能用这些可注入的参数来实例化,这意味着你要么手动实例化你的控制器(使用$controller),几乎从来没有这种情况,或者使用ngRoute 和resolve .对于这样的控制器,你不能用ng-controller 或在注入参数不可用的任何其他位置实例化它。

这个错误表明除了在路由上定义了控制器,你还在路由的模板中定义了ng-controller的控制器。控制器的第二个实例化失败了。

-- StackOver: How to inject dependency from resolve routeProvider


延迟反模式2

dataFetch 服务错误地实现了经典的deferred anti-pattern$http 服务已经返回了一个承诺。无需使用$q.defer() 制造承诺。而是 chain 并从 $http 承诺返回。

angular.module('routeService',[])

.factory('dataFetch', function($http, $q){

    //var deferred = $q.defer();
    var factory = {}
    
    factory.getProposals = function(){

        return $http.get('urlHere')
            .then(function onSuccess(response){    
                console.log("readched the bio service!" + response.data);
                //return to chain data
                return response.data;
    
            }, function onReject(errorResponse){
                //throw to chain rejection
                throw errorResponse;
            });
    };

    return factory;

});

欲了解更多信息,请参阅StackOverflow: Is this a “Deferred Antipattern”?

【讨论】:

    【解决方案2】:

    您可以使用$route 服务访问已解析的值,如here 所述。 此外,您的工厂还有非常烦人的事情。您正在使用全局承诺并在出现错误时返回承诺。那是完全错误的。正确使用promise的方式是

    angular.module('routeService',[])
       .factory('dataFetch', function($http, $q) {
           var factory = {}
           factory.getProposals = function() {
    
              var deferred = $q.defer();
              $http.get('urlHere')
                 .then(function(response) {
                     // Do what else you want to do
                     deferred.resolve(response.data);
                 }, function(response) {
                     // Do what else you want to do
                     deferred.reject(response);
                 });
    
              return deferred.promise;
           };
    
           return factory;
       });
    

    并添加依赖来解析这样的路由中的数据

     $routeProvider
    
        // route for the home page
    
        .when('/', {
            templateUrl: '/overview.html',
            controller: 'login',
            resolve: {
                myDta: function(dataFetch){
                    return dataFetch.getProposals();
                }
            }
    
        })
    

    您可以在login 控制器中访问myDep,如下所示:

     login.controller('login', function($scope, $route) {
        $scope.myDta = $route.current.locals.myDta;
     });
    

    下面是工作示例:http://plnkr.co/edit/WSJk8dhXv1Fvv4yaGf5n?p=preview

    【讨论】:

    • 这不是在控制器加载之前解析数据的角度方式。
    • @MuliYulzary 我只是使用$routes 服务访问解析的数据,因为直接依赖失败了。什么是非角的??
    • 这对我来说似乎没问题。你能解释一下这不是“角度方式”吗?
    • 直接依赖应该可以工作。这里还有别的东西。也滥用 q 服务,但这没什么大不了的
    猜你喜欢
    • 2011-12-21
    • 1970-01-01
    • 2017-09-20
    • 1970-01-01
    • 2021-04-27
    • 2021-08-13
    • 2013-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多