我试图找到动态创建使用指令创建的元素的子内容的最佳方法。
举一个简单的例子,假设我有指示说创建一个基本的div
子元素。
<div mydirective></div>
结果
<div mydirective><div></div></div>
该指令可能类似于:
angular.module('demo', [])
.directive('mydirective', function() {
return {
restrict: 'A',
template: '<div></div>'
}
})
然后说我想创建一个&#34;扩展&#34;这个指令使内部div
变为蓝色。因为我不知道我将来需要哪些扩展,所以我不想切换模板或绑定任何特定属性。
我不知道这些是可能的,或者正常方法是什么......但是你可以
1)向父元素添加一个附加指令(像css一样),即
<div mydirective mybluedirective></div>
mybluedirective
寻找内部div并操纵它?
或
2)你可以在模板中动态包含指令,例如
<div mydirective subdirective="mybluedirective"></div>
angular.module('demo', [])
.directive('mydirective', function() {
return {
restrict: 'A',
template: '<div [[[THE SUBDIRECTIVE PROPERTY FROM SCOPE??]]></div>'
}
})
有没有办法拦截预编译以注入指令?
第三个选项,因为我已经准备好使用工厂和继承的类来完成指令的工作,但这似乎有点过头了。
我猜测有一种我不知道的简单方法,任何建议都值得赞赏
编辑:
我认为我尝试做的是动态修改模板,以便在编译之前使用另一个指令。
答案 0 :(得分:3)
如果要在编译之前动态修改模板,可以使用模板函数:
HTML:
<div mydirective subdirective="mybluedirective"></div>
JS:
angular.module('demo', [])
.directive('mydirective', function() {
return {
restrict: 'A',
template: function(element, attr) {
return '<div ' + attr.subdirective + '></div>'
}
}
})
或者,您可以公开mydirective
mybluedirective
可以使用的API。此解决方案需要mydirective来延迟编译(因为模板将手动编译),并且更多地考虑mydirective
的设计和意图如何扩展:
<强> HTML 强>
<div mydirective mybluedirective></div>
<强> JS 强>
angular.module('demo', [])
.directive('mydirective', function($compile) {
return {
restrict: 'A',
template: '<div></div>',
// we want a child scope so that we don't pollute the parent scope
scope: true,
controller: function($scope, $element) {
var attrs = {};
// expose an API to add attributes dynamically
this.addAttr = function(attr, value) {
attrs[attr] = value;
}
$scope.attrs = attrs;
},
compile: function(element, attr) {
// save the template
var template = element.find('div');
// empty the contents so it is not compiled (we're manually compiling during link)
element.empty();
return function(scope, element, attr) {
// add the attributes to the template
angular.forEach($scope.attrs, function(value, key) {
template.addAttr(key, value);
}
// add the template to the DOM
element.append(template);
// link the template to scope
$compile(template)(scope);
}
}
}
})
.directive('mybluedirective', function() {
return {
restrict: 'A',
require: 'mydirective',
link: function(scope, element, attr, mydirectiveController) {
mydirectiveController.addAttr('ng-class','blue');
}
}
});
答案 1 :(得分:2)
我使用ng-class绑定到指令中的公开变量。您还需要添加范围,如果要设置默认值,则需要添加控制器或链接功能。
以下是一个快速示例:
angular.module('demo', [])
.directive('mydirective', function() {
return {
restrict: 'A',
// add the ng-class to the template. It binds to options.someClass
template: '<div ng-class="options.someClass"></div>',
// give the directive its own Scope with an input object named options
scope: {
options : "="
},
// Give the directive a controller
controller: function($scope) {
// This is an init function to default the input objects
this.onInit = function(){
// If the options object does not exist; create it
if(!$scope.options){
$scope.options = {};
}
// If our custom someClass variable doesn't exist; then give it a default value
if(!$scope.options.someClass){
$scope.options.someClass= "defaultClass";
} }
// call the onInit() function to set up the defaults
onInit();
}
}
})
然后我还提供了一个CSS作为包含默认样式的指令的一部分。你可以相对容易地将它付诸实践。在您的控制器中创建我们的选项对象:
myDirectiveOptions = {
someClass = 'myCustomClass';
}
在您看来,请执行以下操作:
<div mydirective options="myDirectiveOptions"></div>
我发现这很简单,但非常强大。
使用这种方法;动态地改变指令 - ng-class - ;你只需要更新选项对象。在控制器的某个地方,你可以这样做:
myDirectiveOptions.someClass = 'someOtherCustomClass';
由于Angular绑定的魔力,myDirective中的ng-class应该自动拾取它。此更改不必在myDirective的控制器内。
答案 2 :(得分:2)
您可以使用第二个指令来查找第一个指令的结果。只要确保&#34; mybluedirective&#34;优先于&#34; mydirective&#34;。
Js Fiddle:http://jsfiddle.net/XHJC2/
angular.module("demo", []).
controller('SampleCtrl', function ($scope) {
}).
directive('mybluedirective', function () {
return {
priority: 4000,
restrict: 'A',
link: function (scope, elem, attr) {
elem.find('div').html('modified!');
}
};
}).
directive('mydirective', function() {
return {
priority: 40,
restrict: 'A',
template: '<div>TEST</div>'
};
});
以下是关于&#34;优先级&#34;在指令中:https://docs.angularjs.org/api/ng/service/$compile#-priority-