Angular:各州之间的转型应该在哪里?

时间:2015-05-21 15:33:23

标签: javascript angularjs design-patterns

这是一个设计问题:

我正在使用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”,这些都是控制器的上下文,但我仍然会看到转换与实际着陆状态分离。

所以这就是问题:

指定转换到下一个州的最佳位置是什么?

2 个答案:

答案 0 :(得分:0)

您可以使用服务来执行此操作。可以使用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>

答案 1 :(得分:0)

我想出的一个可能性就是这个:

.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)。