Javascript 在使用转换时,元素和属性指令之间有区别吗?
我正试图创建一个具有更高级功能的table指令,但是当我编写构建的基本版本时,遇到了一些我不理解的东西 我有一个名为“njTable”的指令 当我将其用作属性时,它会起作用:Javascript 在使用转换时,元素和属性指令之间有区别吗?,javascript,angularjs,angularjs-directive,angularjs-ng-repeat,Javascript,Angularjs,Angularjs Directive,Angularjs Ng Repeat,我正试图创建一个具有更高级功能的table指令,但是当我编写构建的基本版本时,遇到了一些我不理解的东西 我有一个名为“njTable”的指令 当我将其用作属性时,它会起作用: <body ng-app="tableTest"> <div ng-controller="mainCtrl as mc"> <div></div> <table nj-table> <nj-head> <tr>
<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>
名称
年龄
陈述
{{person.name}
{{person.age}
{{person.state}
但是,当我使用与元素完全相同的指令时,它会中断:
<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>
名称
年龄
陈述
{{person.name}
{{person.age}
{{person.state}
这是一个坏掉的木桶:
以下是功能性Plunker:
也许我不完全理解将指令用作属性与将其用作元素之间的区别?您的指令不能用作元素的原因是浏览器在运行之前呈现HTML并清除任何无效放置的元素 在您的示例中,您有:
<nj-body>
<tr>
上面的HTML无效,因为只有TABLE、THEAD、TFOOT或TBODY元素是TR的有效父元素。
这来自HTML5规范,如下所示:
当浏览器获得此标记时,它会完全删除TR标记,因为它没有以有效的方式使用。当我看到你的(断开的)plunker链接时,chrome控制台抛出了这个错误:
Error: error:tplrt
Invalid Template Root
Template for directive 'njTable' must have exactly one root element.
哪个链接到此angularjs页面:
在初始描述中,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>
名称
年龄
陈述
{{person.name}
{{person.age}
{{person.state}
您的想法是可行的,只是不适用于HTML表格元素,因为它始终是嵌套同级的父元素。这是您的相同想法,但使用div和span
注意:我使用了一些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>
名称
年龄
陈述
{{person.name}
{{person.age}
{{person.state}
以下是正在工作的plunker链接:
完整回答-这不是Angularjs transclude问题,这只是HTML的设计方式。你是说不能使用Angularjs指令创建自定义标记吗?如果你是这么说的,那就不对了,我一直在用Angularjs自定义标记。你可以用Angularjs创建任何你想要的东西,就像这样。你检查过当你使用指令作为元素时,你在返回中指定了“restrict:'E'”吗?或者至少是“restrict:'EA'”?如果你看一下Plunkr,你会发现我就是这么做的,谢谢,我忽略了HTML错误,因为我认为angular会在它运行后修复它