Angularjs:类型错误:无法调用空的方法'的insertBefore“ [英] Angularjs: TypeError: Cannot call method 'insertBefore' of null

查看:129
本文介绍了Angularjs:类型错误:无法调用空的方法'的insertBefore“的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请在这里找到小提琴 http://jsfiddle.net/UxYLa/6/

这是什么,我试图做一个简单的形式。有两个指令,并且嵌套之一,子伪,可动态创建基于选择(随机)HTML表单。如果你反复点击按钮,它会引发以下错误

 类型错误:无法调用空的方法'的insertBefore
    在https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js:138:283
    在Q(https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js:7:332)
    在q.after(https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js:138:258)
    在Object.O(匿名函数)作为后(https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js:139:414)
    在Object.enter(https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js:141:226)
    在Object.move(https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js:141:360)
    在https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js:185:282
    在Object.fn(https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js:99:371)

我发现了这个参考
<一href=\"https://groups.google.com/forum/#!msg/angular/dNra_7P2hwU/09-UBn1XxyUJ\">https://groups.google.com/forum/#!msg/angular/dNra_7P2hwU/09-UBn1XxyUJ
<一href=\"https://github.com/angular/angular.js/issues/2151\">https://github.com/angular/angular.js/issues/2151但我使用的是最新的稳定版本。

这是什么错误的原因。

全部code如下:

脚本:

  VAR对myApp = angular.module('对myApp',[])
    .controller('的TestController',['$范围',函数($范围){
        $ scope.data = {[类型:A,值:[{名:AA},{名字:BB}]},
          {类​​型:B,值:[{名:AA},{名字:BB}]}]
}]);
myApp.directive('指令',函数(){
    返回{
        范围: {
            数据:=,
        },
        限制:'E',
        控制器:函数($范围,$元,$ ATTRS){
            $ scope.random =功能(){
                $ scope.model = $ scope.data [Math.floor(的Math.random()* $ scope.data.length)];
                的console.log($ scope.model)
            };
        },
         模板:'&LT; D​​IV&GT;&LT;按钮NG点击=随机()&GT;随机&LT; /按钮&GT;&lt;副-指令数据=模型&GT;&LT; /分指令&GT;&LT; / DIV&GT;
    };
});
myApp.directive('子伪',函数($ templateCache,$编译){
    返回{
         范围: {
            数据:=,
        },
        限制:'E',
        链接:功能(范围,元素,ATTRS){
             范围。$表(数据,功能(的newval,OLDVAL){
                如果(的newval){
                     element.html($ templateCache.get(newVal.type +'的.html'));
                     $编译(element.contents())(范围);
                 }
             });
        }
    };
});

HTML

 &LT;脚本类型=文/ NG-模板ID =a.html&GT;
     a.html
  &LT; / SCRIPT&GT;
&LT;脚本类型=文/ NG-模板ID =b.html&GT;
      &LT; D​​IV NG重复=ITM数据&GT;
          &LT;跨度NG-IF =串== itm.type'&GT;
              &LT;输入名称='{{itm.Name}}'ID ='{{itm.Name}}'NG-模式='模型[itm.Name]'类型='文本'&GT;&LT; /输入&GT;
          &LT; / SPAN&GT;
      &LT; / DIV&GT;
  &LT; / SCRIPT&GT;&LT; D​​IV NG控制器=的TestController&GT;
    &LT;指令数据=数据&GT;&LT; /指令&GT;
&LT; / DIV&GT;


解决方案

它是与编辑和数据如何绑定。我在这里做了一个工作版本: http://jsfiddle.net/UxYLa/9/

的主要区别是在b.html

 &LT; D​​IV NG-IF =data.values​​&GT;
      &LT; D​​IV NG重复=ITM在data.values​​&GT;
          &LT;输入名称='{{itm.name}}'ID ='{{itm.name}}'NG模型=itm.name类型='文本'&GT;&LT; /输入&GT;
      &LT; / DIV&GT;
  &LT; / DIV&GT;

不得不interate在阵列和参考,而不是模型,ITM,因为它是在范围之内。

编辑:经过一番挖掘这里有一些更多的线索,为什么错误发生,但不是当你将它包装在一个div。它调用这个: parent.insertBefore(节点,index.nextSibling); ,其中父母是你的NG-重复element.parent。如果你没有包装,父为null。

这意味着每当你编译HTML有一个手表是在模板外时,直接更换元件发生错误。

我还提出,并不试图直接改变元件,而是附加编译元件到它的溶液。使一切,当它在消化周期的检查将具有适当的结构。 http://jsfiddle.net/UxYLa/12/

希望这有助于。

Please find the fiddle here http://jsfiddle.net/UxYLa/6/

This is a simplified form of what I am trying to do. There are two directive, and the nested one, subDirective, which dynamically creates html form based on the selection(random). If you click repeatedly on the button, it throws below error

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)

I found a reference about this https://groups.google.com/forum/#!msg/angular/dNra_7P2hwU/09-UBn1XxyUJ https://github.com/angular/angular.js/issues/2151 but I am using the latest stable version.

What is the cause of this error.

Full code below:

script:

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>

解决方案

It has something to do with the compilation and how data is bound. I made a working version here: http://jsfiddle.net/UxYLa/9/

The main differences are in 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>

Have to interate over arrays and refer to itm instead of model since it's in the scope.

Edit: after some digging here are some more clues as to why the error happens, but not when you wrap it in a div. It is calling this: parent.insertBefore(node, index.nextSibling); where parent is element.parent of your ng-repeat. If you don't have the wrapper, the parent is null.

This means the error occurs whenever the html you are compiling has a watch that is on the outside of the template when directly changing the element.

I also made a solution that doesn't attempt to change element directly, but rather appends the compiled element to it. So that everything, when it's checked in the digest cycle will have a proper structure. http://jsfiddle.net/UxYLa/12/

Hope this helped.

这篇关于Angularjs:类型错误:无法调用空的方法'的insertBefore“的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆