【问题标题】:Template must have exactly one root element with custom directive replace: true模板必须只有一个带有自定义指令 replace: true 的根元素
【发布时间】:2016-03-30 07:52:53
【问题描述】:

我在使用 replace: true 的自定义指令时遇到问题,

http://jsbin.com/OtARocO/2/edit

据我所知,我只有一个根元素 my ,这是怎么回事?

Error: Template must have exactly one root element. was: 
<tbody>
  <tr><td>{{ item.name }}</td></tr>
  <tr><td>row2</td></tr>
</tbody>

Javascript:

var app = angular.module("AngularApp", [])
  .directive('custom', [function () {
    return {
      restrict: 'E',
      replace: true,
      templateUrl: 'lineItem.html',
      link: function(scope, element, attrs) {

      }
    };
  }])
.controller('MyCtrl', ['$scope', function($scope) {
  $scope.items = [
    { 
      name: 'foo'
    },
    {
      name: 'bar'
    },
    {
      name: 'baz'
    }
  ];
}]);

HTML:

<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
  <meta name="description" content="Angular Avatar Example" />  

  <script src="//crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/md5.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>


<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body data-ng-app="AngularApp">
  <script type="text/ng-template" id="lineItem.html">
    <tbody>
      <tr><td>{{ item.name }}</td></tr>
      <tr><td>row2</td></tr>
    </tbody>
  </script>
  <div data-ng-controller="MyCtrl">
    <table>
      <custom data-ng-repeat="item in items"></custom>
    </table>
  </div>
</body>
</html>

【问题讨论】:

  • 在此处发布代码和准确完整的错误消息。

标签: angularjs angularjs-directive


【解决方案1】:

似乎是 AngularJs 的 a known bug

您可以做的是将限制更改为属性而不是元素,从模板中删除 tbody 并在您的 html 代码中使用 &lt;tbody custom ng-repeat="item in items"&gt;

基本上:

你的模板变成:

<tr><td>{{ item.name }}</td></tr>
<tr><td>row2</td></tr>

你的指令:

return {
  restrict: 'A',
  templateUrl: 'lineItem.html',
  link: function(scope, element, attrs) {

  }
};

还有你的 HTML:

<div data-ng-controller="MyCtrl">
  <table>
    <tbody custom data-ng-repeat="item in items"></tbody>
  </table>
</div>

【讨论】:

    【解决方案2】:

    还要注意指令模板中的 cmets! docs

    注意模板开头或结尾的 html cmets,因为它们也可能导致此错误。考虑以下模板:

    <div class='container'> 
     <div class='wrapper>
     ...
     </div> <!-- wrapper -->
    </div> <!-- container -->
    

    &lt;!-- container --&gt; 注释被解释为第二个根元素并导致模板无效。

    【讨论】:

      【解决方案3】:

      如果(不存在的)模板的 URL 不正确,也可能会发生此错误。见https://stackoverflow.com/a/34284646/430885

      【讨论】:

        【解决方案4】:

        确保将回显/写入页面的所有 html 元素都已包装在一个信封中。即,如果我的模板将编写一个具有标签、输入 [文本] 和跨度的表单输入。请记住将所有内容都包装在一个 div 中。

        <div>
        <label> My Directive Label</label>
        <input type='text' ng-model='xyz' />
        <span ng-class='errors'></span>
        </div> <!-- the root element , the element that envelops everything-->
        

        您可能收到的另一个错误可能是“未终止的字符串对象”,这意味着模板字符串没有正确终止 - 要解决此问题,只需在每个换行符的末尾添加一个反斜杠字符“\”,即

        .
        .
        replace:true,
        restrict:'ACE',
        template : "<div> \
        <label> My Directive Label</label> \
        <input type='text' ng-model='xyz' /> \
        <span ng-class='errors'></span> \
        </div> \
        ",....
        

        【讨论】:

        • 具有讽刺意味的是,您示例中的尾随 HTML 注释 (&lt;!-- the root element , the element that envelops everything--&gt;) 是 OP 描述的错误的主要原因之一(请参阅此问题的其他回复)。
        猜你喜欢
        • 2015-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-09
        • 2016-09-07
        • 2017-02-02
        • 2017-03-03
        相关资源
        最近更新 更多