Tooltip angular-interfaccia utente con HTML

Attualmente sto aggiungendo alcuni suggerimenti di bootstrap nella mia applicazione.

Tutte le descrizioni “normali” sono ok, ma quando voglio usare tooltip-html-unsafe , tutto quello che ho è un suggerimento vuoto.

Il mio suggerimento:

Help

Nel DOM, ho:

Il contenuto del div sembra vuoto, quindi non c’è nulla da mostrare nel tooltip. Ho provato a inserire direttamente nel DOM del testo HTML come:

test

e funziona.

Hai un’idea?

La direttiva html-safe è progettata per puntare al suo contenuto. Che dire di questo:

 
Help

Quindi, in SomeCtrl, crea una variabile per contenere l’html:

 $scope.yourContent = "my html, yay 

Se si desidera modificare il bootstrap per prelevare il contenuto da un elemento, è ansible farlo in questo modo. Innanzitutto, devi cambiare il modello del tooltip in modo che chiami una funzione per ottenere l’html:

 angular.module("template/tooltip/tooltip-html-unsafe-popup.html", []).run(["$templateCache", function($templateCache) { $templateCache.put("template/tooltip/tooltip-html-unsafe-popup.html", "
\n" + "
\n" + "
\n" + "
\n" + ""); }]);

Quindi, creare una funzione di collegamento per tooltipHtmlUnsafePopup:

 .directive( 'tooltipHtmlUnsafePopup', function () { return { restrict: 'E', replace: true, scope: { content: '@', placement: '@', animation: '&', isOpen: '&' }, templateUrl: 'template/tooltip/tooltip-html-unsafe-popup.html', link: function(scope, element, attrs) { scope.getTooltipHtml = function() { var elemId = '#' + scope.content; var htmlContent = $rootElement.find(elemId).html(); return htmlContent; }; } }; }) 

EDIT: Più tardi ho estratto il codice personalizzato da ui-bootstrap, che è buono dato che non devi modificare ui-bootstrap per usarlo ora. Ecco il codice estratto, in un modulo chiamato “bootstrapx”. Questo è solo per i popover (dato che non stavo davvero usando i tooltip), ma credo che questo dovrebbe essere facilmente adattabile anche ai tooltip.

 angular.module("bootstrapx", ["bootstrapx.tpls","bootstrapx.popover","bootstrapx.popover.dismisser"]); angular.module("bootstrapx.tpls", ["template/popover/popover-html.html","template/popover/popover-html-unsafe.html","template/popover/popover-template.html"]); angular.module( 'bootstrapx.popover', [ 'ui.bootstrap.tooltip' ] ) .directive('popover', [ function() { return { restrict: 'EA', priority: -1000, link: function(scope, element) { element.addClass('popover-link'); } }; }]) .directive('popoverHtml', [ function() { return { restrict: 'EA', priority: -1000, link: function(scope, element) { element.addClass('popover-link'); } }; }]) .directive('popoverHtmlUnsafe', [ function() { return { restrict: 'EA', priority: -1000, link: function(scope, element) { element.addClass('popover-link'); } }; }]) .directive('popoverTemplate', [ function() { return { restrict: 'EA', priority: -1000, link: function(scope, element) { element.addClass('popover-link'); } }; }]) .directive( 'popoverHtmlPopup', [ function() { return { restrict: 'EA', replace: true, scope: { title: '@', content: '@', placement: '@', animation: '&', isOpen: '&' }, templateUrl: 'template/popover/popover-html.html' }; }]) .directive( 'popoverHtml', [ '$compile', '$timeout', '$parse', '$window', '$tooltip', function ( $compile, $timeout, $parse, $window, $tooltip ) { return $tooltip( 'popoverHtml', 'popover', 'click' ); }]) .directive( 'popoverHtmlUnsafePopup', [ '$rootElement', function ( $rootElement ) { return { restrict: 'EA', replace: true, scope: { title: '@', content: '@', placement: '@', animation: '&', isOpen: '&' }, templateUrl: 'template/popover/popover-html-unsafe.html', link: function(scope, element) { var htmlContent = ''; scope.$watch('content', function(value) { if (!value) { return; } var elemId = '#' + value; htmlContent = $rootElement.find(elemId).html(); }); scope.getPopoverHtml = function() { return htmlContent; }; } }; }]) .directive( 'popoverHtmlUnsafe', [ '$compile', '$timeout', '$parse', '$window', '$tooltip', function ( $compile, $timeout, $parse, $window, $tooltip ) { return $tooltip( 'popoverHtmlUnsafe', 'popover', 'click' ); }]) .directive( 'popoverTemplatePopup', [ '$http', '$templateCache', '$compile', '$parse', function ( $http, $templateCache, $compile, $parse) { return { restrict: 'EA', replace: true, scope: { title: '@', content: '@', placement: '@', animation: '&', isOpen: '&' }, templateUrl: 'template/popover/popover-template.html', link: function(scope, element, attrs) { scope.getPopoverTemplate = function() { var templateName = scope.content + '.html'; return templateName; }; } }; }]) .directive( 'popoverTemplate', [ '$compile', '$timeout', '$parse', '$window', '$tooltip', function ( $compile, $timeout, $parse, $window, $tooltip ) { return $tooltip( 'popoverTemplate', 'popover', 'click' ); }]); angular.module("template/popover/popover-html.html", []).run(["$templateCache", function($templateCache) { $templateCache.put("template/popover/popover-html.html", "
\n" + "
\n" + "\n" + "
\n" + "

\n" + "
\n" + "
\n" + "
\n" + ""); }]); angular.module("template/popover/popover-html-unsafe.html", []).run(["$templateCache", function($templateCache) { $templateCache.put("template/popover/popover-html-unsafe.html", "
\n" + "
\n" + "\n" + "
\n" + "

\n" + "
\n" + "
\n" + "
\n" + ""); }]); angular.module("template/popover/popover-template.html", []).run(["$templateCache", function($templateCache) { $templateCache.put("template/popover/popover-template.html", "
\n" + "
\n" + "\n" + "
\n" + "

\n" + "
\n" + "
\n" + "
\n" + ""); }]); angular.module('bootstrapx.popover.dismisser', []) .directive( 'dismissPopovers', [ '$http', '$templateCache', '$compile', '$parse', function ( $http, $templateCache, $compile, $parse) { return { restrict: 'A', link: function(scope, element, attrs) { element.bind('mouseup', function(e) { var clickedOutside = true; $('.popover-link').each(function() { if ($(this).is(e.target) || $(this).has(e.target).length) { clickedOutside = false; return false; } }); if ($('.popover').has(e.target).length) { clickedOutside = false; } if (clickedOutside) { $('.popover').prev().click(); } }); } }; }]);

Ho la direttiva dismissPopovers sul body tag (questo è probabilmente applicabile anche per i tooltip, dovrai solo modificarlo in base alle tue esigenze):

  

Ho creato una direttiva personalizzata che consente di usare tooltips html per bootsrap in modo molto semplice. Non è necessario sovrascrivere alcun modello:

 angular.module('vermouthApp.htmlTooltip', [ ]) .directive('vaTooltip', ['$http', '$templateCache', '$compile', '$parse', '$timeout', function ($http, $templateCache, $compile, $parse, $timeout) { //va-tooltip = path to template or pure tooltip string //tooltip-updater = scope item to watch for changes when template has to be reloaded [optional (only if template is dynamic)] //All other attributes can be added for standart boostrap tooltip behavior (ex. tooltip-placement) return { restrict: 'A', scope: true, compile: function (tElem, tAttrs) { //Add bootstrap directive if (!tElem.attr('tooltip-html-unsafe')) { tElem.attr('tooltip-html-unsafe', '{{tooltip}}'); } return function (scope, element, attrs) { scope.tooltip = attrs.vaTooltip; var tplUrl = $parse(scope.tooltip)(scope); function loadTemplate() { $http.get(tplUrl, { cache: $templateCache }).success(function (tplContent) { var container = $('
'); container.html($compile(tplContent.trim())(scope)); $timeout(function () { scope.tooltip = container.html(); }); }); } //remove our direcive to avoid infinite loop element.removeAttr('va-tooltip'); //compile element to attach tooltip binding $compile(element)(scope); if (angular.isDefined(attrs.tooltipUpdater)) { scope.$watch(attrs.tooltipUpdater, function () { loadTemplate(); }); } else { loadTemplate(); } }; } }; }]);

Ecco come lo chiami

   {{item.properties.length - propertyShowLimit + ' properties more...'}}  

E il modello può essere così:

  

Ora esiste una funzionalità modello buit-in: https://angular-ui.github.io/bootstrap/#tooltip

 Custom template