嵌套的Angular指令无法按预期工作

时间:2014-10-31 12:23:37

标签: angularjs angularjs-directive

我一直在制作一个指令来显示一些HTML并处理事件,因为保持这些代码可重用似乎是明智的。该指令放在ng-repeat中并按预期工作。

现在我来添加一些显示逻辑:2种模式' grid'和'列出',并为每种模式创建2 ng-repeat元素。在这一点上,整个事情似乎因渲染做出一些意想不到的事情而崩溃。

我创建了一个Plunkr来演示:http://plnkr.co/edit/GjxOjxE7KOlvYjxCqVJj?p=preview

App.js

var app = angular.module('myApp', []);

app.directive('documentObject', [function() {
  return {
    restrict: 'E',
    transclude: true,
    scope: {
      object: '=',
      viewmode: '=',
    },
    templateUrl: 'storage-object.html',
    link: function(scope, element, attrs) {
      if (scope.viewMode === 'grid') {
        scope.class = 'grid-view';
      } else {
        scope.class = 'list-view';
      }
    }
  }
}]);

app.controller('DocumentsController', ['$scope', function($scope) {
  $scope.browser = {
    viewMode: 'grid',
    files: [{name: 'First'}, {name: 'Second'}, {name: 'Third'}]
  };
}]);

的index.html

<div ng-switch="browser.viewMode" class="filebrowser">
  <div ng-switch-when="grid">
    <div ng-repeat="file in browser.files">
      <document-object viewmode="browser.viewMode" object="file"></document-object>
    </div>
  </div>
  <table ng-switch-when="list">
    <tr ng-repeat="file in browser.files">
      <document-object viewmode="browser.viewMode" object="file"></document-object>
    </tr>
  </table>
</div>

存储object.html

<div ng-if="viewmode == 'grid'" class="filebrowser {{ viewmode }}">
    Grid Mode: {{ viewmode }}
    <span class="file-label {{ class }}">{{ object.name }}</span>
</div>

<td ng-if="viewmode == 'list'" class="filebrowser {{ viewmode }}">
    List Mode: {{ viewmode }}
    <span class="file-label {{ class }}">{{ object.name }}</span>
</td>

网格模式应仅将项目显示为网格,将列表模式显示为表格。发生的事情是网格模式显示所有内容,列表模式只显示一个元素。

这里发生了什么?

2 个答案:

答案 0 :(得分:2)

之所以发生这种情况,是因为<tr>而不是<td><th>元素的直接子女不允许您拥有任何其他内容。

在你的情况下,你有一个<document-object>元素,这会导致浏览器移动它(因为它不允许在它的位置),这反过来会混淆ng-switch

<document-object>中包装<td></td>并将其模板化(例如将<td>替换为<div>),解决了问题。


的index.html:

...
<table ng-switch-when="list">
    <tr ng-repeat="file in browser.files">
        <td>
            <document-object viewmode="browser.viewMode" object="file"></document-object>
        </td>
    </tr>
</table>

存储object.html:

...
<div ng-if="viewmode == 'list'" class="filebrowser {{ viewmode }}">
    List Mode: {{ viewmode }}
    <span class="file-label {{ class }}">{{ object.name }}</span>
</div>

另请参阅此 updated plunkr

答案 1 :(得分:0)

请参阅此处http://plnkr.co/edit/aMOsKAATd4aBl0swPik1?p=preview

您错过了<td>代码

<table ng-switch-when="list">
  <tr ng-repeat="file in browser.files">
    <td> <!--here -->
      <document-object viewmode="browser.viewMode" object="file"></document-object>
    </td>

  </tr>
</table>