【问题标题】:Is there a difference between Element and Attribute directives when using transclusion?使用嵌入时 Element 和 Attribute 指令之间有区别吗?
【发布时间】:2014-12-02 22:20:49
【问题描述】:

我正在尝试制作一个具有一些更高级功能的 table 指令,但是当我编写要构建的基本版本时,我遇到了一些我不明白的东西。

我有一个名为“njTable”的指令

当我将它用作属性时,它会起作用:

<body ng-app="tableTest">
<div ng-controller="mainCtrl as mc">
  <div></div>
  <table nj-table>
    <nj-head>
      <tr>
        <th>Name</th>
        <th>Age</th>
        <th>State</th>
      </tr>
    </nj-head>
    <nj-body>
      <tr ng-repeat="person in mc.asyncList">
        <td>{{person.name}}</td>
        <td>{{person.age}}</td>
        <td>{{person.state}}</td>
      </tr>
    </nj-body>
  </table>
</div>

但是,当我使用与元素完全相同的指令时,它会中断:

<body ng-app="tableTest">
<div ng-controller="mainCtrl as mc">
  <div></div>
  <nj-table>
    <nj-head>
      <tr>
        <th>Name</th>
        <th>Age</th>
        <th>State</th>
      </tr>
    </nj-head>
    <nj-body>
      <tr ng-repeat="person in mc.asyncList">
        <td>{{person.name}}</td>
        <td>{{person.age}}</td>
        <td>{{person.state}}</td>
      </tr>
    </nj-body>
  </nj-table>
</div>

这是坏掉的 Plunker:http://plnkr.co/edit/zkpPcJG1ZZ5XjORJOoy6?p=preview

这里是功能 Plunker:http://plnkr.co/edit/9W56YRREyuR4ew2rgVUc?p=preview

也许我没有完全理解将指令用作属性与将其用作元素之间的区别?

【问题讨论】:

  • 你是说你不能使用角度指令创建自定义标签吗?如果这就是你所说的那不是真的,我一直在用角度制作自定义标签。
  • 您可以使用 Angularjs 创建任何您想要的东西,例如 DID你检查当你使用指令作为你在返回中指定“restrict:'E'”的元素时?或至少“限制:'EA'”?
  • 如果您查看 Plunkr,您会发现我做到了

标签: javascript angularjs angularjs-directive angularjs-ng-repeat


【解决方案1】:

你的指令不能作为元素起作用的原因是浏览器在 Angular 运行之前渲染 HTML 并清除任何无效放置的元素。

在您的示例中,您有:

<nj-body>
    <tr>

以上是无效的 HTML,因为只有 TABLE、THEAD、TFOOT 或 TBODY 元素是 TR 的有效父元素。 这来自 HTML5 规范,如下所示: http://www.w3.org/TR/html-markup/tr.html

当浏览器得到这个标记时,它会完全删除 TR 标签,因为它没有以有效的方式使用。然后级联到它下面的 TD,依此类推。

【讨论】:

  • 就是这样,谢谢,我忽略了 HTML 错误,因为我认为 Angular 运行后会修复它
【解决方案2】:

当我查看您的(损坏的)plunker 链接时,chrome 控制台抛出此错误:

Error: error:tplrt
Invalid Template Root
Template for directive 'njTable' must have exactly one root element.

链接到这个angularjs页面:

Angularjs Error Link

在最初的描述中,angularjs 链接状态:

When a directive is declared with template (or templateUrl) and replace mode on, 
the template must have exactly one root element.

也许描述可以更明确,并声明“正是一个 HTML 根元素”。 正如 Enzey 所说,在您的情况下,根元素必须是 table 元素,因为它是任何 HTML DOM 中 th、td 和 tr 的父元素,这就是为什么下面的 HTML 和 .

<table class="table table-hover">
  <nj-head>
    <tr>
      <th>Name</th>
      <th>Age</th>
      <th>State</th>
    </tr>
  </nj-head>
  <nj-body>
    <tr ng-repeat="person in mc.asyncList">
      <td>{{person.name}}</td>
      <td>{{person.age}}</td>
      <td>{{person.state}}</td>
    </tr>
  </nj-body>
</table>

您的想法有效,只是不适用于 HTML Table 元素,因为它始终是嵌套兄弟的父级。这是您的相同想法,但使用 Divs 和 Spans。

注意:我使用了一些 CSS 来模仿最初由 Tbootstrap 提供的表格外观。

<nj-table>
  <nj-head>
    <div>
      <span class="tableHeader">Name</span>
      <span class="tableHeader">Age</span>
      <span class="tableHeader">State</span>
    </div>
  </nj-head>
  <nj-body>
    <div ng-repeat="person in mc.asyncList">
      <div class="tableItem">{{person.name}}</div>
      <div class="tableItem">{{person.age}}</div>
      <div class="tableItem">{{person.state}}</div>
    </div>
  </nj-body>
</nj-table>

这是有效的 plunker 链接: Working Plunker Link

为了完成你的答案 - 这不是 Angularjs 的转置问题,它只是 HTML 的设计方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-16
    • 1970-01-01
    • 2012-12-17
    • 2021-07-06
    • 1970-01-01
    相关资源
    最近更新 更多