2016-09-21 29 views
0

我试图让ui路由器的决心将其值传递给控制器​​portalsForUserCtrl角状态解决不注入控制器

这里是路由器:

(function() { 
'use strict'; 

var myApp = angular.module("myApp", ["common.services", "ui.router", 'ngMessages']); 

    myApp.config(["$stateProvider", "$urlRouterProvider", 
    function ($stateProvider, $urlRouterProvider) { 
     $urlRouterProvider.otherwise("/"); 

     $stateProvider 
      .state("portalsForUser", { 
       url: "/userPortal/portalsForUser/:id", 
       templateUrl: "app/userPortal/portalsForUser.html", 
       controller: "portalsForUserCtrl as vm", 
       resolve: { 
        userPortalService: "userPortalService", 
        portalsForUser: function (userPortalService, $stateParams) { 
         var userId = $stateParams.id; 
         console.log(userId); //shows userId correctly 
         return userPortalService.getPortalsForUserPromise(userId) 
          .then(function (response) { 
           var userPortals = response.data; 
           console.log("userPortals", userPortals); //shows portals 
           return userPortals; 
          }); 
        } 
       } 
      }) 
    }] 
); 

这里是整个控制器:

(function() { 
"use strict"; 

angular.module("myApp") 
    .controller("portalsForUserCtrl", portalsForUserCtrl); 

    portalsForUserCtrl.$inject = ['portalsForUser', 'userPortalService']; 

    function portalsForUserCtrl(portalsForUser, userPortalService) { 
    console.log("in portalsForUserCtrl"); 
    var vm = this; 
    vm.portalsForUser = portalsForUser; 
    console.log(portalsForUser); 
    } 

}()); 

在mainCtrl,其是用于index.html中的控制器,I拨打:

$state.go("portalsForUser", ({ "id": userId })); 

以下是查看应用程序/ userPortal/portalsForUser.html的代码:

<div class="container"> 
    <table class="table table-condensed table-striped table-bordered"> 
    <tbody> 
     <tr> 
      <th class="col-md-2">&nbsp;</th> 
      <th class="col-md-4"> 
       Portal Name 
      </th> 
     </tr> 

     <tr ng-repeat="userPortal in vm.portalsForUser"> 
      <td> 
       {{userPortal.portal.portalName}} 
      </td> 
      <td class=""> 
       <a class="btn btn-primary" ui-sref="goSomewhere({id: userPortal.portal.id})"> 
        Go 
       </a> 
      </td> 
     </tr> 
    </tbody> 
</table> 

下面是userPortalService代码:

(function() { 
"use strict"; 

angular.module("myApp") 
    .service('userPortalService', userPortalService); 

userPortalService.$inject = ['userPortalResource', '$http', 'appSettings'] 

    function userPortalService(userPortalResource, $http, appSettings) { 

    var getPortalsForUserPromise = function (id) { 
     return $http.get(appSettings.serverPath + '/api/UserPortal/GetPortalsForUser/' + id); 
    }; 

    return { 
     getPortalsForUserPromise: getPortalsForUserPromise 
    }; 
    } 

}()); 

的网址更改为正确的/userPortal/portalsForUser/:idportalsForUserCtrl功能不火。 只有当我在同一个url上输入enter时,portalsForUserCtrl被实例化并且数据出现在视图中。我错过了什么?

+1

在控制台中的任何错误?我也看不到你的解决方案中需要'userPortalService:“userPortalService” – Phil

+0

控制台没有错误。删除你提到的行没有任何影响,所以你是正确的,这是不需要的,谢谢但是,这种改变并不能解决我的问题。 – Dewey

回答

0

在文档方法的规范中提到以下(https://angular-ui.github.io/ui-router/site/#/api/ui.router.state $ stateProvider):

地图对象是:

关键 - {字符串}:名称注入到控制器的依赖关系 factory - {string | function}:如果字符串是服务的别名。 否则,如果函数,它被注入并返回值,它被视为 依赖项。如果结果是承诺,则在将其值 注入控制器之前解决。

具有以下为例:

resolve: { 
    myResolve1: 
     function($http, $stateParams) { 
      return $http.get("/api/foos/"+stateParams.fooID); 
     } 
    } 

因此,我建议你改变你的代码的其中一个选项,使其作为简单的可能,并使用Chrome开发者工具,放置一个断点上方法的第一行:

resolve: { 
    portalsForUser: ['userPortalService', '$stateParams', function (userPortalService, $stateParams) { 
     var userId = $stateParams.id; //place your breakpoint here 
     return userPortalService.getPortalsForUserPromise(userId); 
    }] 
} 

检查$ stateParams是怎么回事;由于某种原因,目前并不是不可能,因为值不是来自url,所以id属性是未定义的。尝试注入“$ state”并查看$ state.params.id是否包含您期望的内容。 (如此处所述:https://angular-ui.github.io/ui-router/site/#/api/ui.router.state。$ state)。 这里是它可能是什么样子:

resolve: { 
    portalsForUser: ['userPortalService', '$state', function (userPortalService, $state) { 
     var userId = $state.params.id; //place your breakpoint here 
     return userPortalService.getPortalsForUserPromise(userId); 
    }] 
} 

希望,如果它不能解决你的问题,至少它会帮助你找到它。

编辑:

好像以前所有的不走正确的方向。

这是我的新的发展方向: 我用你plunker创建我的电脑上托管网站(使用HTTP服务器:https://www.npmjs.com/package/http-server)。我的版本看起来与你的完全不一样。下面是完整的代码:

app.js:

(function() { 
    'use strict'; 

    var myApp = angular.module("myApp", ["ui.router"]); 

    myApp 
     .config(config) 
     .controller("portalsForUserCtrl", portalsForUserCtrl) 
     .service('userPortalService', userPortalService) 
     .controller("mainCtrl", mainCtrl) 

    mainCtrl.$inject = ["userPortalService", "$state"]; 

    function mainCtrl(userPortalService, $state) { 
     var vm = this; 

     vm.clickMe = function() { 
      var userId = 1; 
      $state.go("portalsForUser", { "id": userId }); 
     } 
    }; 

    config.$inject=["$stateProvider"]; 

    function config($stateProvider) { 
      $stateProvider 
       // PortalsForUser GET 
       .state("portalsForUser", { 
        url: "/userPortal/portalsForUser/:id", 
        templateUrl: "portalsForUser.html", 
        controller: "portalsForUserCtrl as vm", 
        resolve: { 
         portalsForUser: ['userPortalService', '$stateParams', function (userPortalService, $stateParams) { 
          return userPortalService.getPortalsForUserPromise($stateParams.id).then(function(response){return response.data;}); 
         }] 
        } 
       }) 
     } 

    userPortalService.$inject = ['$http', '$q', '$timeout'] 

    function userPortalService($http, $q, $timeout) { 
     var getPortalsForUserPromise = function (id) { 
      var myId=id; 
      var deferred=$q.defer(); 

      $timeout(function(){ 
       deferred.resolve({data:[ 
        { 
        id: 16, 
        portal: { 
         portalName: "Portal1-" + myId, 
         portalId: 1 
        } 
        }, 
        { 
        id: 17, 
        portal: { 
         portalName: "Portal2-" + myId, 
         portalId: 2 
        } 
        } 
       ]}); 
      },5000); 
      return deferred.promise; 
     }; 

     return { 
      getPortalsForUserPromise: getPortalsForUserPromise 
     }; 
    }; 

    portalsForUserCtrl.$inject = ['portalsForUser', 'userPortalService']; 

    function portalsForUserCtrl(portalsForUser, userPortalService) { 
     console.log("in portalsForUserCtrl"); 
     var vm = this; 
     vm.portalsForUser = portalsForUser; 
     console.log(portalsForUser); 
    }; 
}()); 

的index.html:

<html> 
    <head></head> 
</html> 
<body ng-app="myApp"> 
    <!-- bower:js --> 
    <script src="/bower_components/angular/angular.js"></script> 
    <script src="/bower_components/angular-ui-router/release/angular-ui-router.js"></script> 
    <!-- endbower --> 

    <!-- inject:js --> 
    <script src="app.js"></script> 
    <!-- endinject --> 
    <body ng-app="myApp" ng-controller="mainCtrl as vm"> 
     <button type="submit" class="btn btn-default" ng-click="vm.clickMe()"> 
      Click Me 
     </button> 
     <div ui-view></div> 
    </body> 
</body> 

portalsForUser.html:

<div class="container"> 
    Portals For User 
    <table class="table table-condensed table-striped table-bordered"> 
     <tbody> 
      <tr> 
       <th class="col-md-2">&nbsp;</th> 
       <th class="col-md-4"> 
        Portal Name 
       </th> 
      </tr> 

      <tr ng-repeat="userPortal in vm.portalsForUser"> 
       <td> 
        {{userPortal.portal.portalName}} 
       </td> 
       <td class=""> 
        <a class="btn btn-primary" ui-sref="goSomewhere({id: userPortal.portal.id})"> 
         Go 
        </a> 
       </td> 
      </tr> 
     </tbody> 
    </table> 

</div> 

bower.json

{ 
    "name": "test", 
    "description": "just a test", 
    "main": "index.js", 
    "authors": [ 
    "me" 
    ], 
    "license": "ISC", 
    "homepage": "index.html", 
    "private": true, 
    "ignore": [ 
    "**/.*", 
    "node_modules", 
    "bower_components", 
    "test", 
    "tests" 
    ], 
    "dependencies": { 
    "angular": "^1.5.8", 
    "angular-ui-router": "ui-router#^0.3.1" 
    } 
} 

我加入的index.html股利UI视图一样被别人的建议,但我相信这是已经在你最初的项目。 我也尝试模拟服务,像真正的人会工作(与承诺和财产数据)。

你确定你有UI路由器和角度的正确版本?

+0

我已将console.log行添加到'.state'条目的源代码中,以显示$ stateParams正确返回userId。 – Dewey

+0

你能为此做一个运动吗?我们不可能猜到这里发生了什么...... – Stephane

+0

您是否尝试从一开始就重做一个完整的承诺? var def = $ q.defer();并在回调中:def.resolve(userPortals)而不是“return userPortals” – Stephane

1

您在$ state.go语句中有语法错误。

更改此:

$state.go("portalsForUser", ({ "id": userId }));

这样:

$state.go("portalsForUser", { "id": userId });

+0

好的,谢谢,但是改变没有效果。仍然使用正确的stateParam到达“resolve”块。 – Dewey

+0

尝试在then块和console.log之后写入catch块(如果有的话)。此外,你在线'console.log(“userPortals”,userPortals);'解决? –

+0

添加了catch块,但没有错误。在console.log中,我看到了userPortals,所以它们被返回就好了。问题仍然是他们没有被注入控制器。 – Dewey

0

有可能与依赖注入的问题。试试这个 -

resolve: { 
      portalsForUser: ['userPortalService', '$stateParams', function (userPortalService, $stateParams) { 
      var userId = $stateParams.id; 
       return userPortalService.getPortalsForUserPromise(userId) 
         .then(function (response) { 
          var userPortals = response.data; 
          console.log("userPortals", userPortals); 
          return userPortals; 
         }); 
       }] 
      } 
+0

我试过@Kalyan,但它不能解决问题。我仍然需要点击才能使数据显示在视图中。 – Dewey

0

根据您的代码,我已经看到您的控制器与模块clubSkedApp相关联,您的配置与myApp模块相关联。

使用相同的模块两个,或包括控制器这样的模块。

var myApp = angular.module("myApp", ["clubSkedApp","common.services", "ui.router", 'ngMessages']); 

另一种方法是检查为什么没有加载状态。 UI路由器不好引发错误,我发现来检查路线的改变错误的唯一方法是:

myApp.run(runFn); 

runFn.$inject = ['$rootScope']; 

function runFn($rootScope){ 

    //Show the errores caused by the resolve function 
    $rootScope.$on('$stateChangeError', function (event, toState, toParams, 
    fromState, fromParams, error) { 
     event.preventDefault(); 
     console.log(error); 
    }); 
} 
+0

$ stateChangeError是一个好主意。但是,对于我的情况,它不显示任何错误。 – Dewey

+0

你试图将模块名称更改为控制器定义,模块名称 怎么样? –

0

我知道这个问题。解决方案非常简单。

您需要将<div ui-view></div>添加到index.html才能在后面的状态(如下面的代码)中显示您的视图。

<body ng-app="myApp" ng-controller="mainCtrl as vm"> 
    <button type="submit" class="btn btn-default" ng-click="vm.clickMe()"> 
     Click Me 
    </button> 
    <div ui-view></div> 
    </body> 

更多细节