Angular: 状态之间的转换应该在哪里?
Angular: where should transitions among states be?
这是一个设计问题:
我正在使用 Angularjs 制作一个 Web 应用程序,我正在尝试使用 $stateProvider 来模拟应用程序中各个部分的路由。
假设我有两个状态,A 和 B,每个状态都有它的模板和控制器:
.state('A', {
url: "/A",
templateUrl: 'templates/A.html',
controller: 'ACtrl'
})
.state('B', {
url: "/B",
templateUrl: 'templates/B.html',
controller: 'BCtrl'
})
现在假设从 A 开始,在 A 控制器中指定的特定条件下,我需要转到状态 B,我通常会做的是调用 $state.go('B');在 A 控制器中:
.controller('ACtrl', function($scope, $state) {
$scope.gotonext = function(){ $state.go('B'); };
})
现在,在我看来,A 之后的下一个状态应该在我定义路由的地方指定,而不是在 A 的控制器内,像这样:
.state('A', {
url: "/A",
templateUrl: 'templates/A.html',
controller: 'ACtrl',
nextState: 'B' //<-- this line is not angular
})
.controller('ACtrl', function($scope, $state) {
$scope.gotonext = function(){ nextState(); };
})
但是我没有找到做这样的事情的方法。当然,可能不止一个 "nextState",这些与控制器相关,但我仍然会看到转换与实际着陆状态分离。
所以问题是:
指定转换到下一个状态的最佳位置是什么?
您可以使用服务来完成此操作。可以使用 ui router
配置传递自定义数据,因此您可以使用该配置来根据需要定义默认状态。
看下面的代码。
// Global Strings Method to capitalize first letter of string
String.prototype.capitalizeFirstLetter = function() {
return this.charAt(0).toUpperCase() + this.slice(1);
}
angular.module('app', ['ui.router']).config(function($stateProvider, $urlRouterProvider) {
var btnsTemplate = '<button ng-click="gotoPrevious()">previous</button>' +
'<button ng-click="gotoNext()">Next</button>';
$stateProvider.state('A', {
url: '/a',
template: '<div> state A ' + btnsTemplate + '</div>',
controller: 'aController',
defautStates: {
next: 'B', // Will register $scope.gotoNext() method;
previous: 'C' // Will register $scope.gotoPrevious() method;
}
}).state('B', {
url: '/b',
controller: 'bController',
template: '<div> state B ' + btnsTemplate + '</div>',
defautStates: {
next: 'C',
previous: 'A'
}
}).state('C', {
url: '/c',
controller: 'cController',
template: '<div> state C ' + btnsTemplate + '</div>',
defautStates: {
next: 'A',
previous: 'B'
}
});
$urlRouterProvider.otherwise('/a');
}).service('defaultRoutesMethods', function() {
this.register = function(scope, state) {
// Getting default states for current state.
var defautStates = state && state.current && state.current.defautStates;
if (scope && defautStates) {
Object.keys(defautStates).forEach(function(key) {
// generating mathod name using key values of default states object
var methodName = 'goto' + key.capitalizeFirstLetter();
// Adding method goto Methods on current scope.
scope[methodName] = function() {
state.go(defautStates[key]);
}
});
}
};
}).controller('aController', function($scope, $state, defaultRoutesMethods) {
defaultRoutesMethods.register($scope, $state);
}).controller('bController', function($scope, $state, defaultRoutesMethods) {
defaultRoutesMethods.register($scope, $state);
}).controller('cController', function($scope, $state, defaultRoutesMethods) {
defaultRoutesMethods.register($scope, $state);
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.min.js"></script>
<div ng-app="app">
<div ui-view></div>
</div>
我想到的一种可能性是:
.state('A', {
url: "/A",
templateUrl: 'templates/A.html',
controller: 'ACtrl',
resolve: {
transitions: function($state){
return{
nextState: function(){
$state.go('B');
}
};
}
}
})
.controller('ACtrl', function($scope, transitions) {
$scope.gotonext = function(){ transitions.nextState() };
})
我有点喜欢它,因为它保留了路由中指定的转换,而且它也是通用的,因此您可以根据上下文指定您喜欢的所有转换到您的状态(例如 nextState、backState、whateverState)。
这是一个设计问题:
我正在使用 Angularjs 制作一个 Web 应用程序,我正在尝试使用 $stateProvider 来模拟应用程序中各个部分的路由。 假设我有两个状态,A 和 B,每个状态都有它的模板和控制器:
.state('A', {
url: "/A",
templateUrl: 'templates/A.html',
controller: 'ACtrl'
})
.state('B', {
url: "/B",
templateUrl: 'templates/B.html',
controller: 'BCtrl'
})
现在假设从 A 开始,在 A 控制器中指定的特定条件下,我需要转到状态 B,我通常会做的是调用 $state.go('B');在 A 控制器中:
.controller('ACtrl', function($scope, $state) {
$scope.gotonext = function(){ $state.go('B'); };
})
现在,在我看来,A 之后的下一个状态应该在我定义路由的地方指定,而不是在 A 的控制器内,像这样:
.state('A', {
url: "/A",
templateUrl: 'templates/A.html',
controller: 'ACtrl',
nextState: 'B' //<-- this line is not angular
})
.controller('ACtrl', function($scope, $state) {
$scope.gotonext = function(){ nextState(); };
})
但是我没有找到做这样的事情的方法。当然,可能不止一个 "nextState",这些与控制器相关,但我仍然会看到转换与实际着陆状态分离。
所以问题是:
指定转换到下一个状态的最佳位置是什么?
您可以使用服务来完成此操作。可以使用 ui router
配置传递自定义数据,因此您可以使用该配置来根据需要定义默认状态。
看下面的代码。
// Global Strings Method to capitalize first letter of string
String.prototype.capitalizeFirstLetter = function() {
return this.charAt(0).toUpperCase() + this.slice(1);
}
angular.module('app', ['ui.router']).config(function($stateProvider, $urlRouterProvider) {
var btnsTemplate = '<button ng-click="gotoPrevious()">previous</button>' +
'<button ng-click="gotoNext()">Next</button>';
$stateProvider.state('A', {
url: '/a',
template: '<div> state A ' + btnsTemplate + '</div>',
controller: 'aController',
defautStates: {
next: 'B', // Will register $scope.gotoNext() method;
previous: 'C' // Will register $scope.gotoPrevious() method;
}
}).state('B', {
url: '/b',
controller: 'bController',
template: '<div> state B ' + btnsTemplate + '</div>',
defautStates: {
next: 'C',
previous: 'A'
}
}).state('C', {
url: '/c',
controller: 'cController',
template: '<div> state C ' + btnsTemplate + '</div>',
defautStates: {
next: 'A',
previous: 'B'
}
});
$urlRouterProvider.otherwise('/a');
}).service('defaultRoutesMethods', function() {
this.register = function(scope, state) {
// Getting default states for current state.
var defautStates = state && state.current && state.current.defautStates;
if (scope && defautStates) {
Object.keys(defautStates).forEach(function(key) {
// generating mathod name using key values of default states object
var methodName = 'goto' + key.capitalizeFirstLetter();
// Adding method goto Methods on current scope.
scope[methodName] = function() {
state.go(defautStates[key]);
}
});
}
};
}).controller('aController', function($scope, $state, defaultRoutesMethods) {
defaultRoutesMethods.register($scope, $state);
}).controller('bController', function($scope, $state, defaultRoutesMethods) {
defaultRoutesMethods.register($scope, $state);
}).controller('cController', function($scope, $state, defaultRoutesMethods) {
defaultRoutesMethods.register($scope, $state);
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.min.js"></script>
<div ng-app="app">
<div ui-view></div>
</div>
我想到的一种可能性是:
.state('A', {
url: "/A",
templateUrl: 'templates/A.html',
controller: 'ACtrl',
resolve: {
transitions: function($state){
return{
nextState: function(){
$state.go('B');
}
};
}
}
})
.controller('ACtrl', function($scope, transitions) {
$scope.gotonext = function(){ transitions.nextState() };
})
我有点喜欢它,因为它保留了路由中指定的转换,而且它也是通用的,因此您可以根据上下文指定您喜欢的所有转换到您的状态(例如 nextState、backState、whateverState)。