0

我是 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'
        }
    }
  }
]
4

1 回答 1

2

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

  • 您正在使用ui.compat模块。改为使用ui.stateng-view如果您有一个使用and的现有项目,compat 是为了向后兼容routeProvider

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

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

这是我为您制作的 plunkr:http ://plnkr.co/edit/6BEIs6?p=preview


你还说:

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

所以我还做了一个可以根入文件夹的版本(双击它们),就像一个真正的文件浏览器,你也可以返回(单击../)。

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

我认为它非常好,但如果我有更多时间,如果 url 也将您的位置存储在文件夹中会很好(而不是在详细信息中显示什么类型的文件)。


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

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

于 2013-07-14T04:51:38.623 回答