2015-08-20 271 views
1

嗯,我有这个项目,和ui路由器给我很难的时间。我做了一个快速Plunker演示:http://plnkr.co/edit/imEErAtOdEfaMMjMXQfD?p=preview角ui路由器奋斗

所以基本上我有一个主视图,index.html,成其他顶级的观点得到注入,这样operations.index.html。我的大脑中的痛苦开始于顶级视图中存在多个命名视图时,operations.detail.htmloperations.list.html被注入operations.index.html,后者又注入index.html

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

  1. 当用户点击导航栏Operations项目,显示空(新)操作的页面。网址是/operations
  2. 当他们选择一个列表中的项目时,这些字段会更新一些数据(数据通过服务请求,但为了简单起见,我们假设它在控制器中)。网址是/operations/:id
  3. 如果他们决定,他们希望创建一个新的项目,在编辑当前,他们可以单击列表顶部New operation按钮时,URL变化从/operations/:id/operations
  4. 无论新旧项目,导航栏中的项目Operations都保持活动状态。
  5. 如果用户正在编辑一个项目,如果他们创建了一个新项目,应该在列表中高亮显示为活动状态 - New operation按钮应该相应地高亮显示。

现在,查看奇怪的行为:转到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导航条项失去其活动状态或其他奇怪的东西。

我知道问这样的一般性问题在SO中是不常见的,但我实在无法理解ui-router的概念,而且我可以感觉到我在这里做错了事,我会很感激帮助指导我如何正确使用ui-router用于我的目的的正确方向。干杯。

回答

1

the updated plunker

我刚使用的技术从这种问答&答: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

+0

你是一个生命的救星。我真的用尽了我的智力法力来找出像“抽象”等状态设置的所需配置。保存我的是1)添加'redirectTo'设置和'redirector'; 2)将'controller'设置添加到状态,因为现在'$ stateParams.id'在每个路由改变(即选择操作)时被更新。现在没有什么能阻止我们征服世界_hehehe_:D干杯,队友! –

+0

如果这是工作,我真的很高兴。享受强大的UI路由器,先生;) –