使用翻译时,元素和属性指令之间是否存在差异?

时间:2014-12-02 22:20:50

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

我正在尝试创建一个具有更高级功能的表指令但是当我编写基本版本时,我遇到了一些我不理解的东西。

我有一个名为“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

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

2 个答案:

答案 0 :(得分:2)

您的指令不作为元素运行的原因是因为浏览器在Angular运行之前呈现HTML并清除任何无效放置的元素。

在您的示例中,您有:

<nj-body>
    <tr>

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

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

答案 1 :(得分:0)

当我查看你的(破碎的)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根元素。#34; 正如Enzey所说,在你的情况下,根元素必须是一个表元素,因为IT是任何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的设计方式。