Javascript AngularJS:以编程方式重用自定义指令
我正在开发我的第一个单页Angular.js应用程序,并且在以编程方式编译/计算自定义指令以将其从控制器中插入DOM时遇到了一些困难。我创建的自定义指令使用两个值(返回函数并获取参数)和一个参数。在SPA的初始html中使用ng repeat,整个过程都很顺利:Javascript AngularJS:以编程方式重用自定义指令,javascript,angularjs,angular-directive,Javascript,Angularjs,Angular Directive,我正在开发我的第一个单页Angular.js应用程序,并且在以编程方式编译/计算自定义指令以将其从控制器中插入DOM时遇到了一些困难。我创建的自定义指令使用两个值(返回函数并获取参数)和一个参数。在SPA的初始html中使用ng repeat,整个过程都很顺利: .directive('myDirective', ['value1', 'value2', function('value1', 'value2'){ return { restrict: 'E',
.directive('myDirective', ['value1', 'value2', function('value1', 'value2'){
return {
restrict: 'E',
scope: {
param: '=param'
},
replace: true,
templateUrl: '/path/to/template.html',
link: function(scope, element, attrs){
scope.v1 = value1(scope.param);
scope.v2 = value2(scope.param);
}
};
})
指令模板看起来有点像这样:
<div>
<img ng-src="{{ param.img.src }}" />
<div>
<a href="{{ param.link.src }}">{{ param.link.text }}</a>
<time datetime="{{ v1 }}">{{ v2 | date: 'medium' }}</time>
<span ng-bind-html="param.text | customFilter1 | customFilter2 | customFilter3"></span>
</div>
</div>
<ul ng-controller="SomeController" ng-cloak>
<li ng-repeat="param in params">
<my-directive param="param"></my-directive>
</li>
</ul>
结果(即someElement
)确实包含指令的静态html,但不会计算指令中的任何表达式,例如{{param.img.src}
或{v1}
。此外,还会引发以下类型错误:
TypeError: scope.$new is not a function
我尝试使用不同的作用域进行编译,例如控制器的$scope
,或者简单地true
生成一个新的作用域,但是没有一个会计算指令模板中的表达式。在将指令html插入someElement
之后,我还尝试调用$scope.$apply()
,但同样无效
我有点被困在这一点上,没有想法,感谢任何提示。我希望你们能帮我解决这个问题。你们犯错误的第一件事是你们的指令不正确。驼峰形箱子应
-
与所有字母用小箱子隔开
应该是
<my-directive param="param"></my-directive>
p
)应在提供的范围内可解析$scope.p={img:'',…};
$compile(“”)($scope);
删除$scope.p;
我在@vp_rath和@pankajparkar的帮助下解决了这个问题!
问题确实在于$scope
。为了将参数
传递给对$compile()
的调用,我们有两个可能的选项。一种解决方案是将param
绑定到控制器的作用域并添加$watch()
。第二种方法(以及我一直在寻找的更多方法)是:不要绑定到控制器的$scope
,只需创建一个新的普通作用域,如下所示:
// controller:
//
var generateMyDirection = function(param){
var scope = $rootScope.$new();
scope.param = param;
var compiled = $compile('<my-directive param="param"></my-directive>')(scope);
someElement.innerHTML = compiled[0];
};
//控制器:
//
var generateMyDirection=函数(参数){
var scope=$rootScope.$new();
scope.param=param;
已编译变量=$compile(“”)(范围);
someElement.innerHTML=已编译[0];
};
试试$compile(“…”)($scope)
;您提供的是空对象而不是范围。谢谢您的回答!使用$compile(')($scope)
似乎让我更进一步了。但是,现在似乎是方法signuature$scope.generateMyDirective=function(param){…}
的一部分param未传递给指令。这会导致编译模板时出错,例如,无法读取未定义的
的属性“img”。如何确保传递给方法的参数
依次传递给$compile()
中的指令?我的怀疑似乎是正确的。如果在控制器中调用$compile()
之前将param
绑定到$scope
,则每次调用generateMyDirective
都会显示相同的param
,但不会引发错误。一、 但是,我希望避免将方法参数绑定到控制器范围,并且我需要能够为不同的param
s进行编译。是否有其他方法将参数传递给$compile
,从而传递指令?谢谢您的回答!关于camel-case-to-dash分隔符号,我的缺点是,实际指令没有camel-case名称,而是一个简单的小写名称,比如指令
,因此解决了这个问题。使用控制器作用域调用compile会导致以下类型错误:TypeError:无法读取未定义的
的属性“replace”,该属性属于指令中使用的自定义筛选器(使用一些正则表达式替换文本)。我是否需要将过滤器的依赖项注入控制器,尽管它们在html中正常工作?更改为replace:false
不会修复它。我怀疑过滤器中对text.replace(regEx)
的调用导致了错误中的replace
。调用$compile
时似乎没有传递参数
,导致调用未定义。replace(regEx)
反过来导致无法读取属性replace of undefined
。但如何确保在控制器中编译时正确传递参数
?您需要将$watch
放在指令链接内的param上,并在有值时对scope进行操作
<myDirective param="param"></myDirective>
$compile('<my-directive param="param"></my-directive>')($scope);
$scope.p = {img: '', ...};
$compile('<my-directive param="p"></my-directive>')($scope);
delete $scope.p;
// controller:
//
var generateMyDirection = function(param){
var scope = $rootScope.$new();
scope.param = param;
var compiled = $compile('<my-directive param="param"></my-directive>')(scope);
someElement.innerHTML = compiled[0];
};