我在使用AngularJS和ui.router方面遇到了问题。
我有一个应用程序,基本上是用户写信息,发送到服务器,当服务器回答时,我将当前状态更改为通道列表。
我的问题是,通过使用asynchroneus系统,我失去了更改当前状态的能力,没有任何错误,演示:
以下演示是可以的,因为它不使用asynchroneus系统(参见控制台):
代码: http://jsfiddle.net/dievardump/x2tMT/
演示已满: http://jsfiddle.net/dievardump/x2tMT/embedded/result/
这是一个不好的(见控制台)。
代码: http://jsfiddle.net/dievardump/f9rSQ/
演示已满: http://jsfiddle.net/dievardump/f9rSQ/embedded/result/
这两个样本之间的唯一区别在于“platform.channels”状态的声明:
console.log('goes to platform.game');
$state.go('platform.game', {
type: 'gameType',
id: 1
});
VS
setTimeout(function () {
console.log('should go to platform.game');
$state.go('platform.game', {
type: 'gameType',
id: 1
});
}, 1000);
可在本地轻松导入完整演示:
工作:
<div ui-view></div>
<script>
var myApp = angular.module('myApp', ['ui.router']);
myApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/signin");
$stateProvider
.state('platform', {
url: '/platform',
data: {
permissions: ['auth']
},
template: "<section class='platform'>platform<div ui-view></div></section>",
controller: function($state) {
console.log('platformController');
}
});
});
myApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('signin', {
url: "/signin",
template: "<section id='connect' class='connect'><form name='connection' action='' ng-submit='login(connection)'><input placeholder='Choose a nickname' ng-model='nickname' autocomplete='off' /><button><span>Send</span></button></form><p class='error' ng-show='error != null'>{{error}}</p></section>",
controller: function($scope, $state) {
$scope.error = null;
$scope.nickname = null;
$scope.login = function(form) {
var value = $scope.nickname.replace(/[^a-zA-Z0-9]/g, '');
if (value.length >= 3) {
$state.go('platform.channels');
} else {
$scope.error = 'only characters and numbers. length must be >= 3';
}
}
}
});
});
myApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider.state('platform.channels', {
url: "/channels",
template: "<section id='channels' class='channels'>channels</section>",
controller: function($state) {
console.log('channelController');
console.log('goes to platform.game');
$state.go('platform.game', {
type: 'gameType',
id: 1
});
}
})
});
myApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider.state('platform.game', {
url: "/game/:type/:id",
template: "<section id='game' class='game'>game</section>",
controller: function() {
console.log('gameController');
}
});
});
angular.bootstrap(document, ['myApp']);
</script>
不工作:
<div ui-view></div>
<script>
var myApp = angular.module('myApp', ['ui.router']);
myApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/signin");
$stateProvider
.state('platform', {
url: '/platform',
data: {
permissions: ['auth']
},
template: "<section class='platform'>platform<div ui-view></div></section>",
controller: function($state) {
console.log('platformController');
}
});
});
myApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('signin', {
url: "/signin",
template: "<section id='connect' class='connect'><form name='connection' action='' ng-submit='login(connection)'><input placeholder='Choose a nickname' ng-model='nickname' autocomplete='off' /><button><span>Send</span></button></form><p class='error' ng-show='error != null'>{{error}}</p></section>",
controller: function($scope, $state) {
$scope.error = null;
$scope.nickname = null;
$scope.login = function(form) {
var value = $scope.nickname.replace(/[^a-zA-Z0-9]/g, '');
if (value.length >= 3) {
$state.go('platform.channels');
} else {
$scope.error = 'only characters and numbers. length must be >= 3';
}
}
}
});
});
myApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider.state('platform.channels', {
url: "/channels",
template: "<section id='channels' class='channels'>channels</section>",
controller: function($state) {
console.log('channelController');
setTimeout(function () {
console.log('should go to platform.game');
$state.go('platform.game', {
type: 'gameType',
id: 1
});
}, 1000);
}
})
});
myApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider.state('platform.game', {
url: "/game/:type/:id",
template: "<section id='game' class='game'>game</section>",
controller: function() {
console.log('gameController');
}
});
});
angular.bootstrap(document, ['myApp']);
</script>
$ state.go在setTimeout中不起作用的原因是什么?
答案 0 :(得分:2)
你的演示不起作用的原因是超时,当你导致角度知识发生变化时它很简单,角度保持不知道发生的变化因此它不会更新。
解决方案是使用角度方式来做到这一点。 angular提供$timeout
服务。
在此处详细了解:https://docs.angularjs.org/api/ng/service/ $ timeout
工作(此处修复了异步演示):http://jsfiddle.net/f9rSQ/2/
PS你应该总是使用angular的方式或ng- *指令来处理异步更改,如果你通过纯javascript执行它们就不会触发按钮点击事件监听器。为了使它们发射,您可以强制角度运行$digest
周期,这是使用ng-click
,$http
等时以更干净的方式实际发生的事情。