AngularJS : 以编程方式重用自定义指令
AngularJS : Reuse custom directive programmatically
我正在处理我的第一个单页 Angular.js 应用程序,我有点卡在以编程方式 compilling/evaluating 自定义指令,以便从控制器中将其插入 DOM .我创建的自定义指令使用两个值(return 函数并接受一个参数)和一个参数。整个事情在 SPA 的初始 html 中与 ng-repeat 一起工作正常:
.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>
当我像这样在页面 html 中使用此指令时,一切正常:
<ul ng-controller="SomeController" ng-cloak>
<li ng-repeat="param in params">
<my-directive param="param"></my-directive>
</li>
</ul>
我现在想重用该指令,以在控制器内的函数中以编程方式动态生成相应的 html。
我的方法是尝试使用 $compile
函数但没有成功:
// in controller:
// ...
$scope.generateMyDirective = function(param){
var compiled = $compile('<my-directive param="param"></my-directive>')({});
someElement.innerHTML = compiled[0];
};
结果(即 someElement
)确实包含指令的静态 html,但不会计算指令中的任何表达式,例如{{ param.img.src }}
或 {{ v1 }}
。此外抛出以下类型错误:
TypeError: scope.$new is not a function
我尝试使用不同的范围进行编译,例如$scope
控制器或简单地 true
生成一个新的范围,但 none 将计算指令模板中的表达式。我还尝试在将指令 html 插入 someElement
后调用 $scope.$apply()
,但也没有用。
我有点卡在这一点上,没有想法,感谢任何提示。我希望你们能帮我解决这个问题。
您犯错的第一件事是您的指令不正确。驼峰式大小写应 -
与所有小写字母分开
应该是
<my-directive param="param"></my-directive>
而不是
<myDirective param="param"></myDirective>
此外 $compile
应该使用作用域编译元素,你不必担心从控制器创建新的 scope
,你的指令已经有一个独立的作用域。
$compile('<my-directive param="param"></my-directive>')($scope);
- 您应该为指令编译器提供任何范围
- 所有使用的变量(见下文
p
)应该在提供的范围内可解析
$scope.p = {img: '', ...};
$compile('<my-directive param="p"></my-directive>')($scope);
delete $scope.p;
我在@vp_rath 和@pankajparkar 的帮助下解决了这个问题!
问题确实在于$scope
。为了将 param
传递给对 $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];
};
我正在处理我的第一个单页 Angular.js 应用程序,我有点卡在以编程方式 compilling/evaluating 自定义指令,以便从控制器中将其插入 DOM .我创建的自定义指令使用两个值(return 函数并接受一个参数)和一个参数。整个事情在 SPA 的初始 html 中与 ng-repeat 一起工作正常:
.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>
当我像这样在页面 html 中使用此指令时,一切正常:
<ul ng-controller="SomeController" ng-cloak>
<li ng-repeat="param in params">
<my-directive param="param"></my-directive>
</li>
</ul>
我现在想重用该指令,以在控制器内的函数中以编程方式动态生成相应的 html。
我的方法是尝试使用 $compile
函数但没有成功:
// in controller:
// ...
$scope.generateMyDirective = function(param){
var compiled = $compile('<my-directive param="param"></my-directive>')({});
someElement.innerHTML = compiled[0];
};
结果(即 someElement
)确实包含指令的静态 html,但不会计算指令中的任何表达式,例如{{ param.img.src }}
或 {{ v1 }}
。此外抛出以下类型错误:
TypeError: scope.$new is not a function
我尝试使用不同的范围进行编译,例如$scope
控制器或简单地 true
生成一个新的范围,但 none 将计算指令模板中的表达式。我还尝试在将指令 html 插入 someElement
后调用 $scope.$apply()
,但也没有用。
我有点卡在这一点上,没有想法,感谢任何提示。我希望你们能帮我解决这个问题。
您犯错的第一件事是您的指令不正确。驼峰式大小写应 -
与所有小写字母分开
应该是
<my-directive param="param"></my-directive>
而不是
<myDirective param="param"></myDirective>
此外 $compile
应该使用作用域编译元素,你不必担心从控制器创建新的 scope
,你的指令已经有一个独立的作用域。
$compile('<my-directive param="param"></my-directive>')($scope);
- 您应该为指令编译器提供任何范围
- 所有使用的变量(见下文
p
)应该在提供的范围内可解析
$scope.p = {img: '', ...};
$compile('<my-directive param="p"></my-directive>')($scope);
delete $scope.p;
我在@vp_rath 和@pankajparkar 的帮助下解决了这个问题!
问题确实在于$scope
。为了将 param
传递给对 $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];
};