Plnkr 链接 -- link
在上面的plnkr中,我创建了一个名为dynamic-table的自定义指令,它应该接受两个JSON对象作为属性并显示使用这两个JSON生成的表。
下面是 index.html 中的代码,我在其中创建了动态表指令的两个实例 -
<body ng-app="myApp">
<div ng-controller="myCtrl" ng-init="initializeFunction()">
<dynamic-table tablestructure="personDetailsObject" tabledata="personDetailsData"></dynamic-table>
<dynamic-table tablestructure="productTableStructure" tabledata="productTableData"></dynamic-table>
</div>
</body>
渲染的 HTML 并不总是一致,并且第一个表无法加载。看起来这是范围问题,因为有一些变量在实例之间共享并产生问题,但我无法找到解决方案。
此外,我正在使用 arboreal.js 中的 javascript 库,它不是 Angular 。在我的链接函数中使用从此库创建的对象。不确定这是否会造成此问题。
注意 - 如果该指令只有一个实例,则该指令可以正常工作。
请提供相同的解决方案。
最佳答案
好吧,有几件事您没有考虑到。在你的 plunker 中你有这个:
scope.$watch('tablestructure', function(newTablestructure){
generateTheDataStructure(newTablestructure);
});
generateTheDataStructure = function(arguments) {...etc}
由于指令以优先级0
执行,因此在 Controller 之前,由于 Controller 中的初始声明,newTableStructure
的初始值是一个空对象,但是 watch 第一次仍然会执行,然后它将更改为您的 $http
返回的内容。 scope.$watch
将考虑第一个更改,因此将执行 generateTheDataStructure
,但在第一个中执行的 generateTheDataStructure
函数的“版本”指令可能不一定是您在 watch 下方声明的相同函数,因为该指令的第二个实例也在执行,并且该函数是全局赋值,它可能已经可用,所以也许您正在丢失调用该函数的范围,我无法真正告诉这个全局函数发生了什么,但这就是破坏你的指令的原因。
当您在第二个指令中调用 watch 内的 generateTheDataStructure
时,该函数已经存在,因此您的表格可以正常渲染。
为了解决这个问题,您应该在 link
函数的词法范围内对函数进行赋值,如下所示:
var generateTheDataStructure = function(arguments) {...etc}
或者声明它
function generateTheDataStructure(arguments) {...etc}
由于函数声明是提升的,所以第二种方式更安全。我希望对 $digest
循环有更多的了解,以便真正了解这里发生的情况,但这应该可以修复您的指令。
结论: 不要使用全局变量。
关于javascript - 自定义指令的多个实例失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42278002/