2016-09-21 53 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> 

更多細節