[英]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.