[英]Angular state resolve not injecting into controller
我正在嘗試獲取ui路由器的portalsForUserCtrl
以將其值傳遞給控制器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的控制器)中,我調用:
$state.go("portalsForUser", ({ "id": userId }));
以下是視圖app / userPortal / portalsForUser.html的代碼:
<div class="container">
<table class="table table-condensed table-striped table-bordered">
<tbody>
<tr>
<th class="col-md-2"> </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
};
}
}());
URL更改為正確的/userPortal/portalsForUser/:id
但portalsForUserCtrl
函數不會觸發。 只有在我在相同的URL上按回車時,才會實例化portalsForUserCtrl並在視圖中顯示數據。 我想念什么?
$ state.go語句中有語法錯誤。
更改此:
$state.go("portalsForUser", ({ "id": userId }));
。
對此:
$state.go("portalsForUser", { "id": userId });
依賴項注入可能存在問題。 嘗試這個 -
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;
});
}]
}
在文檔( https://angular-ui.github.io/ui-router/site/#/api/ui.router.state。$ stateProvider)上,該方法的規范提到以下內容:
地圖對象是:
鍵-{string}:要注入控制器工廠的依賴項的名稱-{string | function}:如果為string,則它是服務的別名。 否則如果是函數,則將其注入並返回將其視為依賴項的值。 如果結果是承諾,則在將其值注入控制器之前將其解析。
以以下為例:
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);
}]
}
希望它不能解決您的問題,至少可以幫助您找到它。
編輯:
似乎所有以前的方法都不正確。
這是我的新方向:我使用您的竊聽器在計算機上創建了一個托管站點(使用http-server: 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"> </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中添加了div ui-view,但是我相信這已經在您的初始項目中了。 我還試圖模擬服務,就像真正的服務一樣工作(帶有承諾和屬性數據)。
您確定自己的ui-router和angular版本正確嗎?
根據您的代碼,我已經看到您的控制器已與模塊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);
});
}
我知道這個問題。 解決方案非常簡單。
您需要將<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>
欲了解更多信息
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.