使用带有$ stateParams的ui-router的更好方法

时间:2015-12-13 12:54:03

标签: angularjs angular-ui-router

我有一个简单的应用程序,有两个状态。首先显示项目列表,第二个是所选项目的详细视图。我使用$ stateParams作为过滤器来选择详细视图中的特定项目。我想知道是否有更好的方法?

http://plnkr.co/edit/wJeyApEWquqskQot5dS7?p=preview

text = sf.Text(u"Русский текст".decode('cp1253'), font, 16)

2 个答案:

答案 0 :(得分:3)

在我看来,使用嵌套状态网址结构可以达到一个好方法,比你的更友好(或类似休息)......

例如,如果您有一个名为帖子的州,则帖子集合的单个视图应为 posts /:id posts / slug ,slugs比id更可读......

嵌套状态也可以帮助您跟踪当前层次结构。

所以,这可能是你应用的一点重构:

  1. 首先,从控制器中删除所有不需要查看的业务逻辑
  2. //instead of this.items directly in controller, we can create a factory
    
    function ItemsServiceFactory($http, $q) {
      var items = [];
      
      return function getItem(id) {
          if(!id) {
            return $q.when(items);
          }
          
          for(var i = 0, len = items.length; i < len; i++) {
            if(id === items[i].id) {
              return $q.when(items[i]);
            }
          }
          
          return $q.reject(null);
        };
    }
    
    angular
      .module('test', [])
      .factory('ItemsService', ['$http', '$q', ItemsServiceFactory])
    ;

    这样做可以使控制器变亮,并使其仅关注视图所需的内容。

    1. 我们可以围绕其范围重新组织州:
    2. function StatesConfig($stateProvider) {
        var parent = {
          name: 'items',
          url: 'items/',
          abstract: true
        };
        
        var list = {
          name: 'items.list',
          url: '',
          resolve: {
            items: ['ItemsService', function(ItemsService) {
              return ItemsService();
            }]
          },
          views: {
            "main": {
              templateUrl: 'items/list.html',
              controller: 'ItemsListCtrl as items'
            }
          }
        };
      
        var single = {
          name: 'items.single',
          url: ':id/',
          resolve: {
            item: ['ItemsService', '$stateParams', '$state', function(ItemsService, $stateParams, $state) {
              return ItemsService($stateParams.id).catch(function() {
                //Item not found, redirect:
                
                return $state.go('errors.404', {}, { inherit: false });
              });
            }]
          },
          views: {
            "main": {
              templateUrl: 'items/single.html',
              controller: 'ItemsSingleCtrl as item'
            }
          }
        };
        
        $stateProvider
          .state(parent)
          .state(list)
          .state(single)
        ;
      }
      
      angular
        .module('test')
        .config(['$stateProvider'], StatesConfig)
        .controller('ItemsListCtrl', function(items) {
          angular.extend(this, items);
        })
        .controller('ItemsSingleCtrl', function(item) {
          angular.extend(this, item);
        })
      ;

答案 1 :(得分:0)

是的,还有更好的方法。您不应该使用循环来显示单个项目。详细状态应该与列表状态具有单独的控制器。它应该根据作为状态参数传递的ID获取项目,并将此项目(仅此项目)公开给视图。

在真实应用中,这将包括向后端发出GET请求以获取该项目。在您的简单应用程序中,项目列表在代码中是硬编码的,列表可以存储在服务中,与两个控制器共享。列表控制器将从服务中获取整个列表。详细控制器会要求服务返回具有给定ID的项目。