我想在自定义事件上显示bootstrap popover(从服务器加载数据后)。我不明白为什么这段代码不起作用。 JSFiddle
第二个问题,如果设置replace = true
,如何触发事件?因为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);
}
};
}
};
}]);
答案 0 :(得分:0)
好的,我找到了解决方案。
首先,在根模板元素上混合replace=true
和ng-if
是一个坏主意。接下来,我将角度/广播事件和原生js事件分开。 popover仍然需要本机事件。
<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);
}
};
}
};
}]);