Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从另一个指令静态添加AngularJS指令_Javascript_Angularjs_Angularjs Directive - Fatal编程技术网

Javascript 从另一个指令静态添加AngularJS指令

Javascript 从另一个指令静态添加AngularJS指令,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,我正在尝试使用一个带有一些静态但复杂内容的引导popover(通过ui引导) popover本身可以工作——将其直接应用于特定元素会导致其按预期显示: <div data-popover="test"></div> 这似乎和预期的一样有效。我的问题是:这是正确的做法吗?是否有任何负面后果?除了升级,还有更好的方法获得一次性绑定支持吗 Edit:一个明显的负面后果是,如果元素有其他复杂的指令(特别是ngRepeat;也可能是ngIf等,那么这个额外的编译就不能正常工作。)

我正在尝试使用一个带有一些静态但复杂内容的引导popover(通过ui引导)

popover本身可以工作——将其直接应用于特定元素会导致其按预期显示:

<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);
        },
    };
}]);