Angularjs:类型错误:无法调用空的方法'的insertBefore“ [英] Angularjs: TypeError: Cannot call method 'insertBefore' of null
问题描述
请在这里找到小提琴 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; DIV&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; DIV 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; DIV NG控制器=的TestController&GT;
&LT;指令数据=数据&GT;&LT; /指令&GT;
&LT; / DIV&GT;
它是与编辑和数据如何绑定。我在这里做了一个工作版本: http://jsfiddle.net/UxYLa/9/
的主要区别是在b.html
&LT; DIV NG-IF =data.values&GT;
&LT; DIV 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屋!