Angularjs:TypeError:无法调用null的方法'insertBefore'

时间:2014-01-28 23:49:43

标签: javascript angularjs

请在此处找到小提琴http://jsfiddle.net/UxYLa/6/

这是我想要做的简化形式。有两个指令,和嵌套的一个subDirective,它根据选择(随机)动态创建html表单。如果您在按钮上反复单击,则会抛出错误

TypeError: Cannot call method 'insertBefore' of null
    at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js:138:283
    at q (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js:7:332)
    at q.after (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js:138:258)
    at Object.O.(anonymous function) [as after] (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js:139:414)
    at Object.enter (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js:141:226)
    at Object.move (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js:141:360)
    at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js:185:282
    at Object.fn (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js:99:371)

我找到了关于此的参考 https://groups.google.com/forum/#!msg/angular/dNra_7P2hwU/09-UBn1XxyUJ https://github.com/angular/angular.js/issues/2151但我使用的是最新的稳定版本。

此错误的原因是什么。

以下完整代码:

脚本:

var myApp = angular.module('myApp', [])
    .controller('TestController', ['$scope', function ($scope) {
        $scope.data = [{ type: "a", values: [{name:"aa"}, {name: "bb"}]},
          { type: "b", values: [{name:"aa"}, {name: "bb"}]}]
}]);   
myApp.directive('directive', function () {
    return {
        scope: {
            data: "=",
        },
        restrict: 'E',
        controller: function ($scope, $element, $attrs) {
            $scope.random = function(){
                $scope.model = $scope.data[Math.floor(Math.random()*$scope.data.length)];
                console.log($scope.model)
            };
        },
         template: '<div><button ng-click="random()">Random</button><sub-directive data="model"></sub-directive></div>'
    };
});


myApp.directive('subDirective', function ($templateCache, $compile) {
    return {    
         scope: {
            data: "=",
        },
        restrict: 'E', 
        link: function (scope, element, attrs) {
             scope.$watch('data', function (newVal, oldVal) {
                if (newVal) {
                     element.html($templateCache.get(newVal.type + '.html'));
                     $compile(element.contents())(scope);
                 }
             });
        }
    };
});

HTML

  <script type="text/ng-template" id="a.html">
     a.html
  </script>


<script type="text/ng-template" id="b.html">
      <div ng-repeat="itm in data">
          <span ng-if='"string" == itm.type'>
              <input name='{{itm.Name}}'id='{{itm.Name}}' ng-model='model[itm.Name]' type='text'></input>
          </span>
      </div>
  </script>

<div ng-controller="TestController">
    <directive data="data"></directive>
</div>

5 个答案:

答案 0 :(得分:17)

我有同样的错误消息。我可以通过在我的html脚本标记中引用Angular 之前的JQuery来解决这个问题。

答案 1 :(得分:12)

它与编译以及数据绑定方式有关。我在这里制作了一个工作版:http://jsfiddle.net/UxYLa/9/

主要区别在于b.html

  <div ng-if="data.values">
      <div ng-repeat="itm in data.values">
          <input name='{{itm.name}}' id='{{itm.name}}' ng-model="itm.name" type='text'></input>
      </div>
  </div>

必须与数组进行交互并引用它而不是模型,因为它在范围内。

编辑:经过一些挖掘,这里有一些关于错误发生原因的更多线索,但不是当你将它包装在div中时。它调用它:parent.insertBefore(node, index.nextSibling);其中parent是ng-repeat的element.parent。如果您没有包装器,则父级为空。

这意味着只要您正在编译的html在直接更改元素时有一个位于模板外部的监视,就会发生错误。

我还提出了一个解决方案,它不会直接尝试更改元素,而是将编译后的元素附加到它上面。因此,当在摘要周期中检查时,所有内容都将具有适当的结构。 http://jsfiddle.net/UxYLa/12/

希望这会有所帮助。

答案 2 :(得分:1)

我遇到了同样的问题,但我发现我在class="md-sticky"标记上添加了<md-subheader>,这意味着要说class="md-no-sticky"

一旦我改变了这个课程,就为我排序了问题,但我也有同样的问题,使用ng-repeat而不是它自己的父标签,但我有!我只是在父标记上使用ng-show="condition",如果该父标记没有显示它会导致此问题,所以我将其更改为ng-if="condition"并对该问题进行了排序。

答案 3 :(得分:0)

我有完全相同的问题,似乎解决它的问题是删除了我在其中一个div上的“ng-view”类。这就像是在引发冲突。

我有:

<div class="ng-view"> 
  <div ng-view>
    ...

然后改为:

<div class="ngview">
  <div ng-view>
    ...

我猜测ng-view是一个保留字,但我认为当用作类时它不会受到影响。

答案 4 :(得分:0)

我在使用UI-Router时遇到了同样的问题,并且A标签在href属性中的URL不是路径。