[英]Angular state resolve not injecting into controller
I'm trying to get ui-router's resolve to pass its value to the controller portalsForUserCtrl
. 我正在尝试获取ui路由器的
portalsForUserCtrl
以将其值传递给控制器portalsForUserCtrl
。
Here is the router: 这是路由器:
(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;
});
}
}
})
}]
);
Here is the entire controller: 这是整个控制器:
(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);
}
}());
In mainCtrl, which is the controller for index.html, I call: 在mainCtrl(它是index.html的控制器)中,我调用:
$state.go("portalsForUser", ({ "id": userId }));
Here is the code for the view app/userPortal/portalsForUser.html: 以下是视图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>
Here is the code for the userPortalService: 这是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
};
}
}());
The url changes to the correct /userPortal/portalsForUser/:id
but the portalsForUserCtrl
function does not fire. URL更改为正确的
/userPortal/portalsForUser/:id
但portalsForUserCtrl
函数不会触发。 It is only when I hit enter on the same url that portalsForUserCtrl is instantiated and the data appears in the view. 只有在我在相同的URL上按回车时,才会实例化portalsForUserCtrl并在视图中显示数据。 What am I missing?
我想念什么?
You have a syntax error in the $state.go statement. $ state.go语句中有语法错误。
Change this: 更改此:
$state.go("portalsForUser", ({ "id": userId }));
. 。
to this: 对此:
$state.go("portalsForUser", { "id": userId });
There might be an issue with dependency injection. 依赖项注入可能存在问题。 Try this -
尝试这个 -
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;
});
}]
}
On the documentation ( https://angular-ui.github.io/ui-router/site/#/api/ui.router.state .$stateProvider) the specification of the method mentions the following: 在文档( https://angular-ui.github.io/ui-router/site/#/api/ui.router.state。$ stateProvider)上,该方法的规范提到以下内容:
The map object is:
地图对象是:
key - {string}: name of dependency to be injected into controller factory - {string|function}: If string then it is alias for service.
键-{string}:要注入控制器工厂的依赖项的名称-{string | function}:如果为string,则它是服务的别名。 Otherwise if function, it is injected and return value it treated as dependency.
否则如果是函数,则将其注入并返回将其视为依赖项的值。 If result is a promise, it is resolved before its value is injected into controller.
如果结果是承诺,则在将其值注入控制器之前将其解析。
with the following as an example: 以以下为例:
resolve: {
myResolve1:
function($http, $stateParams) {
return $http.get("/api/foos/"+stateParams.fooID);
}
}
So I suggest you change your code into one of these options to make it as simple a possible and, using chrome developer tool, place a breakpoint on the first line on the method: 因此,我建议您将代码更改为以下选项之一,以使其尽可能简单,并使用chrome开发人员工具,在该方法的第一行上放置一个断点:
resolve: {
portalsForUser: ['userPortalService', '$stateParams', function (userPortalService, $stateParams) {
var userId = $stateParams.id; //place your breakpoint here
return userPortalService.getPortalsForUserPromise(userId);
}]
}
Check what is going on with $stateParams; 用$ stateParams检查发生了什么; it is not impossible that, for some reason, at this moment, everything is not initialized yet because values don't come from the url, therefore, the id property is undefined.
由于某种原因,由于当前值并非来自url,因此由于某种原因,目前还没有全部初始化是不可能的,因此id属性是未定义的。 Try to inject "$state" and see if $state.params.id contains what you expect instead.
尝试注入“ $ state”,然后查看$ state.params.id是否包含您期望的内容。 (like mentioned in here: https://angular-ui.github.io/ui-router/site/#/api/ui.router.state .$state).
(如此处所述: https : //angular-ui.github.io/ui-router/site/#/api/ui.router.state。$ state)。 Here is what it could look like:
看起来像这样:
resolve: {
portalsForUser: ['userPortalService', '$state', function (userPortalService, $state) {
var userId = $state.params.id; //place your breakpoint here
return userPortalService.getPortalsForUserPromise(userId);
}]
}
Hope that if it doesn't solve your problem, at least it will help you to find it. 希望它不能解决您的问题,至少可以帮助您找到它。
EDIT: 编辑:
It seems all the previous doesn't go to the right direction. 似乎所有以前的方法都不正确。
Here is my new direction: I used your plunker to create a hosted site on my computer (using http-server: https://www.npmjs.com/package/http-server ). 这是我的新方向:我使用您的窃听器在计算机上创建了一个托管站点(使用http-server: https ://www.npmjs.com/package/http-server)。 My version that doesn't seem to be very different than yours works perfectly.
我的版本似乎与您的版本没有太大不同,但效果很好。 Here is the full code:
这是完整的代码:
app.js: 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: 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: 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 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"
}
}
I added the div ui-view in index.html like suggested by somebody else, but I believe this was already in your initial project. 我像其他人建议的那样在index.html中添加了div ui-view,但是我相信这已经在您的初始项目中了。 I also tried to simulate the service like the real one would work (with a promise and with a property data).
我还试图模拟服务,就像真正的服务一样工作(带有承诺和属性数据)。
Are you sure you have correct versions of ui-router and angular? 您确定自己的ui-router和angular版本正确吗?
Based in your code, I've seen that the your controller it's associated to the module clubSkedApp
and your config it's associated to the myApp
module. 根据您的代码,我已经看到您的控制器已与模块
clubSkedApp
关联,而您的配置已与myApp
模块关联。
Use the same module for both, or include the module of your controller like this. 两者都使用相同的模块,或者像这样包含控制器的模块。
var myApp = angular.module("myApp", ["clubSkedApp","common.services", "ui.router", 'ngMessages']);
Another approach is check why the state it's not loaded. 另一种方法是检查为什么未加载状态。 Ui-router isn't good to raise errors, the only way that i find to check the errors in a route's change is the following:
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);
});
}
I know the problem. 我知道这个问题。 The solution is very simple.
解决方案非常简单。
You need to add <div ui-view></div>
into index.html to display your view in the later state like below code. 您需要将
<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>
For more detail 欲了解更多信息
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.