Javascript 从另一个指令静态添加AngularJS指令
我正在尝试使用一个带有一些静态但复杂内容的引导popover(通过ui引导) popover本身可以工作——将其直接应用于特定元素会导致其按预期显示:Javascript 从另一个指令静态添加AngularJS指令,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,我正在尝试使用一个带有一些静态但复杂内容的引导popover(通过ui引导) popover本身可以工作——将其直接应用于特定元素会导致其按预期显示: <div data-popover="test"></div> 这似乎和预期的一样有效。我的问题是:这是正确的做法吗?是否有任何负面后果?除了升级,还有更好的方法获得一次性绑定支持吗 Edit:一个明显的负面后果是,如果元素有其他复杂的指令(特别是ngRepeat;也可能是ngIf等,那么这个额外的编译就不能正常工作。)
<div data-popover="test"></div>
这似乎和预期的一样有效。我的问题是:这是正确的做法吗?是否有任何负面后果?除了升级,还有更好的方法获得一次性绑定支持吗
Edit:一个明显的负面后果是,如果元素有其他复杂的指令(特别是
ngRepeat
;也可能是ngIf
等,那么这个额外的编译就不能正常工作。)这里的问题是,popover的自动初始化只会在dom就绪事件中发生一次,之后所做的任何更改都不会初始化插件
所以试着自己初始化插件
module.directive('generatePopover', ['myService', function (myService) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var key = scope.$eval(attrs.generatePopover);
var content = myService.getPopoverText(key);
element.removeAttr('data-generate-popover');
//set the popover content here
element.attr('data-content', content);
//here initialize the
element.popover();
},
};
}]);
您不应该太担心angular在每个摘要周期上执行所有观察者,否则您永远不会停止担心。即使像这样一个简单的绑定
{{key}}
实际上也是一个在每个摘要周期上解析scope.key
的函数。事实上,它甚至在每个消化周期中进行多次
这就是Angular的工作原理(至少在1.3之前,这将随着Angular 2的出现而完全改变),而且它已经得到了很好的优化:您唯一需要关心的是使函数getPopoverText
尽可能快:这里严格禁止jQuery
如果你真的想这么做,你的方法似乎是正确的。如果您仍然希望键
得到更新,但只能在您做出决定时更新,而不是在每个摘要周期更新,您可以添加
scope.$on('popover.update', updateThePopover);
并在每次需要时广播此事件。但是,同样,一个典型的angular应用程序可以有数千个观察者,如果观察者本身编码良好,那么它的执行仍然非常顺利,因此我强烈建议不要浪费时间,为其中的一个应用程序复杂化代码,而要专注于使用一个尽可能简单的getPopoverText
方法。这只是我个人经验的一个建议
PS:为了减少执行的观察者数量,请尝试在许多独立的指令中对应用程序进行模块化,并且更喜欢
scope.$digest
而不是scope.$apply
只对独立的作用域进行摘要,而不是对所有的作用域进行摘要。发布这个问题后,我简化了一些事情(尽管有一些双重处理,我并不完全满意):
module.directive('generatePover',['myService',function(myService){
返回{
限制:“A”,
优先事项:10,
链接:函数(范围、元素、属性){
var key=作用域$eval(attrs.generatePover);
element.removeAttr(属性$attr.GeneratePover);
scope.tooltip=myService.getPopoverText(键);
},
};
}]);
(在这种情况下,我知道每个作用域只有一个由ngRepeat
定义的更高级别,因此我不需要担心多个工具提示会相互覆盖。)
话虽如此,这仍然是一个黑客行为,我期待着在升级AngularJS时用一次性绑定取代它。可以在指令模板中使用ng bind html
,并删除大量代码一次性绑定怎么样,即data popopover=“{{{::getpopopertext(key)}”
<div data-generate-popover="key"></div>
module.directive('generatePopover', ['myService', function(myService) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var key = scope.$eval(attrs.generatePopover);
var content = myService.getPopoverText(key);
element.removeAttr('data-generate-popover');
element.attr('data-popover', content);
},
};
}]);
module.directive('generatePopover',
['myService', '$compile',
function(myService, $compile) {
return {
restrict: 'A',
priority: 10000,
link: {
pre: function (scope, element, attrs) {
var key = scope.$eval(attrs.generatePopover);
var content = myService.getPopoverText(key);
element.removeAttr('data-generate-popover');
element.attr('data-popover', content);
$compile(element)(scope);
}
},
};
}]);
module.directive('generatePopover', ['myService', function (myService) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var key = scope.$eval(attrs.generatePopover);
var content = myService.getPopoverText(key);
element.removeAttr('data-generate-popover');
//set the popover content here
element.attr('data-content', content);
//here initialize the
element.popover();
},
};
}]);
scope.$on('popover.update', updateThePopover);
<div data-generate-popover="key" data-popover="{{tooltip}}"></div>
module.directive('generatePopover', ['myService', function(myService) {
return {
restrict: 'A',
priority: 10,
link: function (scope, element, attrs) {
var key = scope.$eval(attrs.generatePopover);
element.removeAttr(attrs.$attr.generatePopover);
scope.tooltip = myService.getPopoverText(key);
},
};
}]);