简体   繁体   English

如何在自定义事件上显示角度引导弹出窗口?

[英]How to show angular bootstrap popover on custom event?

I want to display bootstrap popover on custom event (after loading data from server). 我想在自定义事件上显示引导程序弹出窗口(从服务器加载数据之后)。 I don't understand why this code don't work. 我不明白为什么这段代码行不通。 JSFiddle JSFiddle

And second question, how to trigger events if I set replace = true ? 第二个问题,如果我设置replace = true ,如何触发事件? Because of IE8 doesn't support custom tags and throws exception. 由于IE8不支持自定义标签,因此会引发异常。

<div ng-app="tcApp">
    <manual></manual>
</div>
var tcApp = angular.module('tcApp', [ 'ui.bootstrap' ]);

tcApp.config(function ($tooltipProvider) {
    $tooltipProvider.setTriggers({
        'openAfterLoad': 'closeOnClick'
    });
});

tcApp.directive('manual', [ '$timeout', '$interval', function($timeout, $interval) {
    return {
        restrict: 'E',
        scope: {},
        template: 
    '<a ' + 
'   href="#" ' + 
'   ng-if="isManualVisible" ' + 
'   popover-append-to-body="true" ' + 
'   popover-placement="bottom" ' + 
'   popover-trigger="openAfterLoad" ' + 
'   popover-title="{{title}}" ' + 
'   popover="{{content}}" ' + 
'   tooltip="{{title}}" ' + 
'   >' + 
'   <span class="{{textClass}}">' + 
'       <span ng-show="!loading" class="glyphicon glyphicon-question-sign"></span>' + 
'       <span ng-show="loading" class="glyphicon glyphicon-refresh"></span>' + 
'   </span>' + 
'</a>',
        replace: false, // true for IE8 only
        link: function (scope, element, attr) {

            scope.isManualVisible = true;
            scope.title = 'First title value';
            scope.content = 'First content value';
            scope.textClass = 'text-info';

            scope.opened = false;
            scope.loading = false;
            scope.loaded = false;
            scope.loadedTitle = false;
            scope.loadedContent = false;
            scope.checkLoadState = function () {
                if (scope.loadedTitle && scope.loadedContent) {
                    scope.loaded = true;
                    if (scope.loading)
                        scope.loading = false;
                    element.triggerHandler('openAfterLoad');
                }
            };
            scope.$watch('loadedTitle', scope.checkLoadState);
            scope.$watch('loadedContent', scope.checkLoadState);

            element.on('openAfterLoad', function(event) {
                console.log('openAfterLoad');
                scope.opened = true;
            });

            element.on('closeOnClick', function(event) {
                console.log('closeOnClick');
                scope.opened = false;
            });

            element.on('click', function(event) {
                console.log('click');
                if (scope.loaded) {
                    if (scope.opened)
                        element.triggerHandler('closeOnClick');
                    else
                        element.triggerHandler('openAfterLoad');
                } else {
                    scope.loadData();
                }
            });

            scope.loadData = function() {
                if (!scope.loaded && !scope.loading) {
                    scope.loading = true;

                    $interval(function() {
                        scope.title = 'New title value';
                        scope.loadedTitle = true;
                    }, 5000, 1);

                    $interval(function() {
                        scope.content = 'New content value';
                        scope.loadedContent = true;
                    }, 5000, 1);
                }
            };
        }
    };
}]);

Ok, I'm found solution. 好的,我找到了解决方案。

First of all, mixing of replace=true and ng-if on root template element is a bad idea. 首先,在根模板元素上混合replace=trueng-if是一个坏主意。 Next, I separated angular on/broadcast events and native js events. 接下来,我分离了角度上/广播事件和本机js事件。 Native events still required for popover. 弹出事件仍然需要本机事件。

JSFiddle JSFiddle

<div ng-app="tcApp">
    <manual></manual>
</div>
var tcApp = angular.module('tcApp', [ 'ui.bootstrap' ]);

tcApp.config(function ($tooltipProvider) {
    $tooltipProvider.setTriggers({
        'openAfterLoad': 'closeOnClick'
    });
});

tcApp.directive('manual', [ '$timeout', '$interval', function($timeout, $interval) {
    return {
        restrict: 'E',
        scope: {},
        template: 
    '<a ' + 
'   href="#" ' + 
'   ng-show="isManualVisible" ' +
'   ng-click="clickHandler()" ' +
'   popover-append-to-body="true" ' + 
'   popover-placement="bottom" ' + 
'   popover-trigger="openAfterLoad" ' + 
'   popover-title="{{title}}" ' + 
'   popover="{{content}}" ' + 
'   tooltip="{{title}}" ' + 
'   >' + 
'   <span class="{{textClass}}">' + 
'       <span ng-show="!loading" class="glyphicon glyphicon-question-sign"></span>' + 
'       <span ng-show="loading" class="glyphicon glyphicon-refresh"></span>' + 
'   </span>' + 
'</a>',
        replace: true, // true for IE8 only
        link: function (scope, element, attr) {

            scope.isManualVisible = true;
            scope.title = 'First title value';
            scope.content = 'First content value';
            scope.textClass = 'text-info';

            scope.opened = false;
            scope.loading = false;
            scope.loaded = false;
            scope.loadedTitle = false;
            scope.loadedContent = false;
            scope.checkLoadState = function () {
                if (scope.loadedTitle && scope.loadedContent) {
                    scope.loaded = true;
                    if (scope.loading)
                        scope.loading = false;
                    scope.$broadcast('openAfterLoad');
                }
            };
            scope.$watch('loadedTitle', scope.checkLoadState);
            scope.$watch('loadedContent', scope.checkLoadState);

            scope.$on('openAfterLoad', function(event) {
                console.log('openAfterLoad');
                scope.opened = true;
                $timeout(function() {
                    // trigger popover
                    element.triggerHandler('openAfterLoad');
                });
            });

            scope.$on('closeOnClick', function(event) {
                console.log('closeOnClick');
                scope.opened = false;
                $timeout(function() {
                    // trigger popover
                    element.triggerHandler('closeOnClick');
                });
            });

            scope.clickHandler = function(event) {
                console.log('click');
                if (scope.loaded) {
                    if (scope.opened)
                        scope.$broadcast('closeOnClick');
                    else
                        scope.$broadcast('openAfterLoad');
                } else {
                    scope.loadData();
                }
            };

            scope.loadData = function() {
                if (!scope.loaded && !scope.loading) {
                    scope.loading = true;

                    $interval(function() {
                        scope.title = 'New title value';
                        scope.loadedTitle = true;
                    }, 2000, 1);

                    $interval(function() {
                        scope.content = 'New content value';
                        scope.loadedContent = true;
                    }, 3000, 1);
                }
            };
        }
    };
}]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM