Angular ui-router斗争

时间:2015-08-20 14:44:43

标签: angularjs angular-ui-router state

好吧,我有这个项目,ui-router给了我很多困难。我做了一个快速的Plunker演示:http://plnkr.co/edit/imEErAtOdEfaMMjMXQfD?p=preview

所以基本上我有一个主视图index.html,其中注入了其他顶级视图,例如operations.index.html。当顶级视图中有多个命名视图时,我的大脑开始出现疼痛,operations.detail.htmloperations.list.html被注入operations.index.html,然后注入index.html

基本上,我想要实现的是以下行为:

  1. 当用户点击导航栏中的Operations项时,会显示一个包含空(新)操作的页面。该网址为/operations
  2. 当他们选择列表中的项目时,字段会更新一些数据(数据是通过服务请求的,但为了简单起见,我们假设它正好在控制器中)。该网址为/operations/:id
  3. 如果他们决定要创建新项目,则在修改当前项目时,他们点击列表顶部的New operation按钮,网址会从/operations/:id更改为/operations
  4. 无论是新项目还是旧项目,导航栏中的项目Operations都会保持有效状态。
  5. 如果用户正在修改项目,则应在列表中将其突出显示为活动状态,如果他们创建了新项目,则应突出显示New operation按钮。
  6. 现在,查看奇怪的行为:转到Operations,然后再次点击Operations导航栏项。一切都消失了。如果我做Operations - >同样的情况也会发生选择Operation 1 - >选择New operation

    此外,请查看我尝试获取id参数的部分:

    $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
      if (toParams) {
        if (toParams.id) {
          for (var i = 0; i < vm.operations.length; i++) {
            if (vm.operations[i].id == toParams.id) {
              vm.operation = vm.operations[i];
              break;
            }
          }
        }
      }
    });
    

    我不是专家,但它似乎太长而且复杂,尤其是对于获取请求参数这样的简单任务。如果我尝试检查状态更改$stateParams,则对象为空,因此这种解决方法。如果我试图篡改app.js中的状态,事情就会略有改变,但总会出现Operations导航栏项失去其活动状态或其他奇怪内容的错误。

    我知道提出这样的一般性问题并不常见,但我真的无法理解ui-router的概念,我觉得我在这里做错了,我真的很感激任何帮助指出我正确的方向如何正确使用ui-router为我的目的。欢呼声。

1 个答案:

答案 0 :(得分:1)

the updated plunker

我刚使用了此Q&amp;答:Redirect a state to default substate with UI-Router in AngularJS

我添加了 redirectTo 设置(可能处于任何状态)

.state('operations', {
      url: '/operations',
      templateUrl: 'operations.index.html',
      controller: 'operationsController as op',
      // here is redirect
      redirectTo: 'operations.new',
 })

并添加了 redirector

app.run(['$rootScope', '$state', function($rootScope, $state) {

    $rootScope.$on('$stateChangeStart', function(evt, to, params) {
      if (to.redirectTo) {
        evt.preventDefault();
        $state.go(to.redirectTo, params)
      }
    });
}]);

而且,我删除了当前位于operationsController.js的重定向:

angular.module('uiRouterApp')
  .controller('operationsController', function($state, $stateParams, $rootScope) {
    var vm = this;

    //if ($state.current.name === 'operations') $state.go('operations.new');

以上所有只是为了保持新状态 - 没有网址。因为解决方案会变得更加容易,如果我们只是介绍url: '/new'

.state('operations', {
  url: '/operations',
  ..
})
.state('operations.new', {
  //url: '',
  url: '/new',

检查plunker here

所以,通过这种方式,我们为路由赋予了生命。现在是时候让细节工作了。要实现这一目标,我们需要更多 - there is another updated plunker

首先,我们会将全新的 controller添加到子状态视图中:

.state('operations.new', {
  url: '',
  views: {
    'detail': {
      templateUrl: 'operations.detail.html',
      controller: 'detailCtrl as dc',         // here new controller
   ...
})
.state('operations.detail', {
  url: '/:id',
  views: {
    'detail': {
      templateUrl: 'operations.detail.html',
      controller: 'detailCtrl as dc',         // here new controller
    ...

它们可能是同一个控制器,因为我们会在$stateParams.id的内容上保持新的或现有的决策。这将是它的实施:

.controller('detailCtrl', function($scope, $state, $stateParams) {
    var op = $scope.op;

    op.operation = {id:op.operations.length + 1};

    if ($stateParams.id) {
      for (var i = 0; i < op.operations.length; i++) {
        if (op.operations[i].id == $stateParams.id) {
          op.operation = op.operations[i];
          break;
        }
      }
    }
})

我们保留原始方法,并在选择 $stateParams.id 时设置op.operation。如果没有,我们会创建新项目, id 会正确递增。

现在我们只调整父控制器,不保存现有的,只是新的:

  .controller('operationsController', function($state, $stateParams, $rootScope) {
    var vm = this;

    //if ($state.current.name === 'operations') $state.go('operations.new');

    vm.operation = {};

    /*$rootScope.$on('$stateChangeStart', 
                    function(event, toState, toParams, fromState, fromParams) {
      if (toParams) {
        if (toParams.id) {
          for (var i = 0; i < vm.operations.length; i++) {
            if (vm.operations[i].id == toParams.id) {
              vm.operation = vm.operations[i];
              break;
            }
          }
        }
      }
    });*/

    vm.save = function() {

      if(vm.operations.indexOf(vm.operation) >= 0){
        return;
      }
      if (vm.operation.name 
      && vm.operation.description 
      && vm.operation.quantity) {
        vm.operations.push(vm.operation);
        vm.operation = {id: vm.operations.length + 1};
      }
    };

检查complete version here