正确使用AngularJS中的视图和子视图

时间:2013-07-12 15:08:02

标签: angularjs view angular-ui

我是AngularJS的新手,我在多个视图中苦苦挣扎。也许有人可以说明如何做到这一点。

我想要实现的目标: 我正在尝试实现某种文件资源管理器,其中有两列:左列包含文件夹中的所有子文件夹和文件,右列显示单击文件或文件夹时的详细信息。当用户双击文件夹时,视图应刷新并列出子文件夹,同时应清除详细信息列。

它基本上或多或少地起作用,但即使它不应该,左栏也总是令人耳目一新。而且我很确定它非常hacky,但我不知道如何改进它。

我正在使用ui-router作为多个视图,而Restangular用于REST调用,在本例中我将其替换为虚拟数据。

自举:

// app.js
var app = angular.module('explorer', ['ui.compat']);

这是我的主要模板:

// app.html
[...]
[...]
<div ui-view></div>

这是容器模板,在最开始时加载:

// files.html
<div ui-view></div>
<div ui-view="details"></div>

这是左侧文件列表的模板:

// files-list.html
<table>
    <thead>
    <tr>
        <th>Filename</th>
        <th>Size</th>
        <th>Modified</th>
    </tr>
    </thead>
    <tbody>
    <tr data-ng-repeat="file in files">
        <td><a href="#/{{ file.type }}/{{ file.id }}">{{ file.name }}</a></td>
        <td>{{ file.size }}</td>
        <td>{{ file.modified }}</td>
    </tr>
    </tbody>
</table>

这是详细信息模板:

// files-details.html
<div>{{ file.name }}</div>

这是第一个在左栏显示列表的控制器(抱歉,它是CoffeScript):

app.controller 'ListController', ['$scope', '$state', ($scope, $state) ->
  $scope.files = [{
    "id": "12", "type": "folder", "name": "testfolder", "size": "", "modified": "01.01.2000"
  }, {
    "id": "54", "type": "file", "name": "testfile", "size": "23kb", "modified": "01.01.2000"
  }]
]

这是细节控制器:

app.controller 'DetailsController', ['$scope', '$stateParams', ($scope, $stateParams) ->
  $scope.file = { "id": "54", "type": "file", "name": "testfile", "size": "23kb", "modified": "01.01.2000"};
]

这些是我凌乱的路由规则:

app.config ['$stateProvider', '$urlRouterProvider', ($stateProvider, $urlRouterProvider) ->
  $urlRouterProvider
    .when('/folder', '/folder/1')

  $stateProvider.state 'list', {
    url: ''
    views: {
      '': {
        templateUrl: 'files.html'
      },
      'column1@list': {
        templateUrl: 'files-list.html'
        controller: 'ListController'
      },
      'column2@list': {
        templateUrl: 'files-detail.html'
      }
    }
  }
  $stateProvider.state 'folder', {
    abstract: yes
    templateUrl: 'files-list.html'
    controller: 'ListController'
  }
  $stateProvider.state 'folder.list', {
    url: '/folder/{id}'
    templateUrl: 'files-list.html'
    controller: 'ListController'
  }

  $stateProvider.state 'list.file', {
    url: '/file/{childId}'
    views: {
      '': {
        templateUrl: 'files-list.html'
        controller: 'ListController'
      }
      'details': {
          templateUrl: 'files-detail.html'
          controller: 'DetailsController'
        }
    }
  }
]

1 个答案:

答案 0 :(得分:2)

但是我看到了一些你可能不正确的事情。

  • 您正在使用ui.compat模块。请改用ui.state。如果您有使用ng-viewrouteProvider的现有项目,则compat用于向后兼容。

  • 我会将详细信息视图嵌入文件列表视图中。这有帮助,因为现在当您在文件之间切换时,只有详细信息视图更新,而不是列表。我添加了一个日志来证明这一点。请看下面的我的plunkr。从文件夹导航到文件并返回几次。 “list”控制器只实例化一次。

  • 我还将您的详细状态合并为一个状态为url: "/:type/:id"的网址,因此它会捕获/ folder / id和/ file / id

这是我为你做的一个傻瓜:http://plnkr.co/edit/6BEIs6?p=preview


你也说过:

  

当用户双击文件夹时,视图应刷新并列出   应删除详细信息列时的子文件夹。

所以我还创建了一个可以根据文件夹(双击它们)的版本,就像真正的文件浏览器一样,你也可以重新启动(单击../)。

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

我认为它非常好,但如果我有更多时间,如果网址还将您的位置存储在文件夹中(而不是在详细信息中显示哪种类型的文件),那就太好了。


编辑:所以我想尝试弄清楚如何使文件夹路径同步到位置路径。好吧,我想出来了,但它需要手动做很多。例如,我只有1个状态,其网址为“* path”,它只捕获整个路径甚至是'/'字符。然后我必须解析它并使它做我需要它。见plunkr:

http://plnkr.co/edit/1dDN3x?p=preview