Javascript AngularJS ui路由器$state.go(';^';)仅更改地址栏中的URL,但不加载控制器
我正在尝试用angularjsJavascript AngularJS ui路由器$state.go(';^';)仅更改地址栏中的URL,但不加载控制器,javascript,angularjs,angular-ui-router,Javascript,Angularjs,Angular Ui Router,我正在尝试用angularjsui路由器创建一个“Todo应用程序”。它有两列: 第1列:待办事项列表 第2列:待办事项详细信息或待办事项编辑表单 在保存Todo后的编辑和创建控制器中,我希望重新加载列表以显示相应的更改。问题:在创建或更新Todo时,调用$state.go(“^”)后,浏览器中的URL会更改回/api/Todo,但不会执行ListCtrl,即未调用$scope.search,因此不会检索Todo列表(包含更改的项目),第2列中也没有显示第一个Todo的详细信息(而是变为空白
ui路由器创建一个“Todo应用程序”。它有两列:
- 第1列:待办事项列表
- 第2列:待办事项详细信息或待办事项编辑表单
在保存Todo后的编辑和创建控制器中,我希望重新加载列表以显示相应的更改。问题:在创建或更新Todo时,调用$state.go(“^”)
后,浏览器中的URL会更改回/api/Todo
,但不会执行ListCtrl,即未调用$scope.search
,因此不会检索Todo列表(包含更改的项目),第2列中也没有显示第一个Todo的详细信息(而是变为空白)
我甚至尝试了$state.go('^',$stateParams,{reload:true,inherit:false,notify:false})代码>,运气不好
如何进行状态转换以最终执行控制器?
资料来源:
var TodoApp = angular.module('TodoApp', ['ngResource', 'ui.router'])
.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/api/todo');
$stateProvider
.state('todo', {
url: '/api/todo',
controller: 'ListCtrl',
templateUrl: '/_todo_list.html'
})
.state('todo.details', {
url: '/{id:[0-9]*}',
views: {
'detailsColumn': {
controller: 'DetailsCtrl',
templateUrl: '/_todo_details.html'
}
}
})
.state('todo.edit', {
url: '/edit/:id',
views: {
'detailsColumn': {
controller: 'EditCtrl',
templateUrl: '/_todo_edit.html'
}
}
})
.state('todo.new', {
url: '/new',
views: {
'detailsColumn': {
controller: 'CreateCtrl',
templateUrl: '/_todo_edit.html'
}
}
})
;
})
;
TodoApp.factory('Todos', function ($resource) {
return $resource('/api/todo/:id', { id: '@id' }, { update: { method: 'PUT' } });
});
var ListCtrl = function ($scope, $state, Todos) {
$scope.todos = [];
$scope.search = function () {
Todos.query(function (data) {
$scope.todos = $scope.todos.concat(data);
$state.go('todo.details', { id: $scope.todos[0].Id });
});
};
$scope.search();
};
var DetailsCtrl = function ($scope, $stateParams, Todos) {
$scope.todo = Todos.get({ id: $stateParams.id });
};
var EditCtrl = function ($scope, $stateParams, $state, Todos) {
$scope.action = 'Edit';
var id = $stateParams.id;
$scope.todo = Todos.get({ id: id });
$scope.save = function () {
Todos.update({ id: id }, $scope.todo, function () {
$state.go('^', $stateParams, { reload: true, inherit: false, notify: false });
});
};
};
var CreateCtrl = function ($scope, $stateParams, $state, Todos) {
$scope.action = 'Create';
$scope.save = function () {
Todos.save($scope.todo, function () {
$state.go('^');
});
};
};
我可能遇到过类似的问题,我采用的方法是使用$location.path(data.path).search(data.search)
重定向页面,然后在控制器中捕获$locationChangeSuccess事件。换句话说,我使用$location.path(…).search(…)
作为$state.go(…)
的对应项,然后捕获$locationChangeSuccess事件,该事件将在匹配路由和调用控制器之前发生位置更改时触发
var TodoApp = angular.module('TodoApp', ['ngResource', 'ui.router'])
.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/api/todo');
$stateProvider
.state('todo', {
url: '/api/todo',
controller: 'ListCtrl',
templateUrl: '/_todo_list.html'
})
.state('todo.details', {
url: '/{id:[0-9]*}',
views: {
'detailsColumn': {
controller: 'DetailsCtrl',
templateUrl: '/_todo_details.html'
}
}
})
.state('todo.edit', {
url: '/edit/:id',
views: {
'detailsColumn': {
controller: 'EditCtrl',
templateUrl: '/_todo_edit.html'
}
}
})
.state('todo.new', {
url: '/new',
views: {
'detailsColumn': {
controller: 'CreateCtrl',
templateUrl: '/_todo_edit.html'
}
}
})
;
})
;
TodoApp.factory('Todos', function ($resource) {
return $resource('/api/todo/:id', { id: '@id' }, { update: { method: 'PUT' } });
});
var ListCtrl = function ($scope, $state, Todos, todo.details) {
/*here is where i would make the change*/
$scope.$on('$locationChangeSuccess', function () {
$scope.search();
$route.reload();
});
$scope.todos = [];
$scope.search = function () {
Todos.query(function (data) {
$scope.todos = $scope.todos.concat(data);
});
};
$scope.search();
};
var DetailsCtrl = function ($scope, $stateParams, Todos) {
$scope.todo = Todos.get({ id: $stateParams.id });
};
var EditCtrl = function ($scope, $stateParams, $state, Todos, $location) {
$scope.action = 'Edit';
var id = $stateParams.id;
$scope.todo = Todos.get({ id: id });
$scope.save = function () {
Todos.update({ id: id }, $scope.todo, function () {
//here is where I would make a change
$location.path('todo.details').search($stateParams);
});
};
};
var CreateCtrl = function ($scope, $stateParams, $state, Todos, $location) {
$scope.action = 'Create';
$scope.save = function () {
Todos.save($scope.todo, function () {
//here is where I would make a change
$location.path('todo.details');
});
};
};
$LOCATIONCHANGESSUCCESS事件发生在匹配路由和调用控制器之前我将给出一个示例(草稿),说明如何将编辑
嵌套到详细信息中。首先,让我们修改模板
详细信息
模板包含详细信息的完整定义。另外,它现在包含属性ui view=“editView”
。这将确保编辑将从可见性角度“替换”细节,而编辑范围将继承所有细节设置。这就是ui路由器的威力
有了这个调整的状态
和模板
映射,我们确实有很多。现在我们可以充分利用ui路由器
我们将在DetailCtrl
上定义一些方法(记住,在继承编辑状态下可用)
好的,现在应该很清楚了,我们确实有一个模型
,带有model.todos
项及其备份model.original
编辑控制器可以有两个操作:Save()
和Cancel()
这应该会让我们知道如何在父/子状态之间导航,以及如何强制重新加载
请注意,事实上,我使用的不是Angular.copy(),而是Angular.copy(),但两者都应该可以工作非常感谢Radim Köhler指出,$scope
是继承的。通过两个小改动,我成功地解决了这个问题。请参阅下面的代码,我在添加额外行的地方进行了注释。现在它就像一个符咒
var TodoApp = angular.module('TodoApp', ['ngResource', 'ui.router'])
.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/api/todo');
$stateProvider
.state('todo', {
url: '/api/todo',
controller: 'ListCtrl',
templateUrl: '/_todo_list.html'
})
.state('todo.details', {
url: '/{id:[0-9]*}',
views: {
'detailsColumn': {
controller: 'DetailsCtrl',
templateUrl: '/_todo_details.html'
}
}
})
.state('todo.edit', {
url: '/edit/:id',
views: {
'detailsColumn': {
controller: 'EditCtrl',
templateUrl: '/_todo_edit.html'
}
}
})
.state('todo.new', {
url: '/new',
views: {
'detailsColumn': {
controller: 'CreateCtrl',
templateUrl: '/_todo_edit.html'
}
}
})
;
})
;
TodoApp.factory('Todos', function ($resource) {
return $resource('/api/todo/:id', { id: '@id' }, { update: { method: 'PUT' } });
});
var ListCtrl = function ($scope, $state, Todos) {
$scope.todos = [];
$scope.search = function () {
Todos.query(function (data) {
$scope.todos = $scope.todos(data); // No concat, just overwrite
if (0 < $scope.todos.length) { // Added this as well to avoid overindexing if no Todo is present
$state.go('todo.details', { id: $scope.todos[0].Id });
}
});
};
$scope.search();
};
var DetailsCtrl = function ($scope, $stateParams, Todos) {
$scope.todo = Todos.get({ id: $stateParams.id });
};
var EditCtrl = function ($scope, $stateParams, $state, Todos) {
$scope.action = 'Edit';
var id = $stateParams.id;
$scope.todo = Todos.get({ id: id });
$scope.save = function () {
Todos.update({ id: id }, $scope.todo, function () {
$scope.search(); // Added this line
//$state.go('^'); // As $scope.search() changes the state, this is not even needed.
});
};
};
var CreateCtrl = function ($scope, $stateParams, $state, Todos) {
$scope.action = 'Create';
$scope.save = function () {
Todos.save($scope.todo, function () {
$scope.search(); // Added this line
//$state.go('^'); // As $scope.search() changes the state, this is not even needed.
});
};
};
var TodoApp=angular.module('TodoApp',['ngResource','ui.router']))
.config(函数($stateProvider,$urlRouterProvider){
$urlRouterProvider。否则('/api/todo');
$stateProvider
.州(‘待办事项’{
url:“/api/todo”,
控制器:“ListCtrl”,
templateUrl:“/\u todo\u list.html”
})
.state('todo.details'{
url:“/{id:[0-9]*}”,
观点:{
“详情栏”:{
控制器:“DetailsCtrl”,
templateUrl:“/\u todo\u details.html”
}
}
})
.state('todo.edit'{
url:“/edit/:id”,
观点:{
“详情栏”:{
控制器:“EditCtrl”,
templateUrl:“/\u todo\u edit.html”
}
}
})
.state('todo.new'{
url:“/new”,
观点:{
“详情栏”:{
控制器:“CreateCtrl”,
templateUrl:“/\u todo\u edit.html”
}
}
})
;
})
;
TodoApp.factory('Todos',函数($resource){
返回$resource('/api/todo/:id',{id:'@id'},{update:{method:'PUT'}});
});
var ListCtrl=函数($scope、$state、Todos){
$scope.todos=[];
$scope.search=函数(){
Todos.query(函数(数据){
$scope.todos=$scope.todos(数据);//没有concat,只是覆盖
如果(0<$scope.todos.length){//也添加了此项,以避免在没有Todo时过度索引
$state.go('todo.details',{id:$scope.todos[0].id});
}
});
};
$scope.search();
};
var DetailsCtrl=函数($scope、$stateParams、Todos){
$scope.todo=Todos.get({id:$stateParams.id});
};
var EditCtrl=函数($scope、$stateParams、$state、Todos){
$scope.action='Edit';
var id=$stateParams.id;
$scope.todo=Todos.get({id:id});
$scope.save=函数(){
update({id:id},$scope.todo,函数(){
$scope.search();//添加了此行
//$state.go('^');//当$scope.search()更改状态时,甚至不需要这样做。
});
};
};
var CreateCtrl=function($scope、$stateParams、$state、Todos){
$scope.action='Create';
$scope.save=函数(){
保存($scope.todo,函数(){
$scope.search();//添加了此行
//$state.go('^');//当$scope.search()更改状态时,甚至不需要这样做。
});
};
};
我想说,这是对各州的误解。检查。当应用程序处于特定sta时
// keep detail definition as it is
.state('todo.details', {
url: '/{id:[0-9]*}',
views: {
'detailsColumn': {
controller: 'DetailsCtrl',
templateUrl: '/_todo_details.html'
}
}
})
// brand new definition of the Edit
.state('todo.details.edit', { // i.e.: url for detail like /todo/details/1/edit
url: '/edit',
views: {
'editView': { // inject into the parent/detail view
controller: 'EditCtrl',
templateUrl: '/_todo_edit.html'
}
}
})
var DetailsCtrl = function ($scope, $stateParams, Todos) {
$scope.id = $stateParams.id // keep it here
// model will keep the item (todos) and a copy for rollback
$scope.model = {
todos : {},
original : {},
}
// declare the Load() method
$scope.load = function() {
Todos
.get({ id: $stateParams.id })
.then(function(response){
// item loaded, and its backup copy created
$scope.model.todos = response.data;
$scope.model.original = angular.copy($scope.model.todos);
});
};
// also explicitly load, but just once,
// not auto-triggered when returning back from Edit-child
$scope.load()
};
var EditCtrl = function ($scope, $stateParams, $state, Todos) {
$scope.action = 'Edit';
// ATTENTION, no declaration of these,
// we inherited them from parent view !
//$scope.id .. // we DO have them
//$scope.model ...
// the save, then force reload, and return to detail
$scope.save = function () {
Todos
.update({ id: id })
.then(function(response){
// Success
$scope.load();
$state.go('^');
},
function(reason){
// Error
// TODO
});
};
// a nice and quick how to rollback
$scope.cancel = function () {
$scope.model.todos = Angular.copy($scope.model.original);
$state.go('^');
};
};
var TodoApp = angular.module('TodoApp', ['ngResource', 'ui.router'])
.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/api/todo');
$stateProvider
.state('todo', {
url: '/api/todo',
controller: 'ListCtrl',
templateUrl: '/_todo_list.html'
})
.state('todo.details', {
url: '/{id:[0-9]*}',
views: {
'detailsColumn': {
controller: 'DetailsCtrl',
templateUrl: '/_todo_details.html'
}
}
})
.state('todo.edit', {
url: '/edit/:id',
views: {
'detailsColumn': {
controller: 'EditCtrl',
templateUrl: '/_todo_edit.html'
}
}
})
.state('todo.new', {
url: '/new',
views: {
'detailsColumn': {
controller: 'CreateCtrl',
templateUrl: '/_todo_edit.html'
}
}
})
;
})
;
TodoApp.factory('Todos', function ($resource) {
return $resource('/api/todo/:id', { id: '@id' }, { update: { method: 'PUT' } });
});
var ListCtrl = function ($scope, $state, Todos) {
$scope.todos = [];
$scope.search = function () {
Todos.query(function (data) {
$scope.todos = $scope.todos(data); // No concat, just overwrite
if (0 < $scope.todos.length) { // Added this as well to avoid overindexing if no Todo is present
$state.go('todo.details', { id: $scope.todos[0].Id });
}
});
};
$scope.search();
};
var DetailsCtrl = function ($scope, $stateParams, Todos) {
$scope.todo = Todos.get({ id: $stateParams.id });
};
var EditCtrl = function ($scope, $stateParams, $state, Todos) {
$scope.action = 'Edit';
var id = $stateParams.id;
$scope.todo = Todos.get({ id: id });
$scope.save = function () {
Todos.update({ id: id }, $scope.todo, function () {
$scope.search(); // Added this line
//$state.go('^'); // As $scope.search() changes the state, this is not even needed.
});
};
};
var CreateCtrl = function ($scope, $stateParams, $state, Todos) {
$scope.action = 'Create';
$scope.save = function () {
Todos.save($scope.todo, function () {
$scope.search(); // Added this line
//$state.go('^'); // As $scope.search() changes the state, this is not even needed.
});
};
};