12

Attualmente sto aggiungendo alcune descrizioni comandi di bootstrap nella mia applicazione.Tooltip angolare-interfaccia utente con HTML

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

Il mio suggerimento:

<a><span tooltip-placement="right" tooltip-html-safe="{{myHTMLText}}"> Help </span></a>

nel DOM, ho: contenuti

<div class="tooltip-inner" ng-bind-html-unsafe="content"></div>

del div sembra vuota, quindi non c'è niente da mostrare nel suggerimento. Ho provato a inserire direttamente nel DOM del testo HTML come:

<div class="tooltip-inner" ng-bind-html-unsafe="content"><b>test</b></div> e funziona.

Avete un'idea?

risposta

23

La direttiva html non sicura è progettata per indicare il suo contenuto. Che dire di questo:

Poi, nel SomeCtrl, fanno una variabile per contenere il codice HTML:

$scope.yourContent = "<b>my html, yay</b> 

se si desidera modificare bootstrap per prendere il contenuto da un elemento, si può fare come questo. In primo luogo, è necessario modificare il modello di tooltip in modo che chiama una funzione per ottenere il codice HTML:

angular.module("template/tooltip/tooltip-html-unsafe-popup.html", []).run(["$templateCache", function($templateCache) { 
    $templateCache.put("template/tooltip/tooltip-html-unsafe-popup.html", 
    "<div class=\"tooltip {{placement}}\" ng-class=\"{ in: isOpen(), fade: animation() }\">\n" + 
    " <div class=\"tooltip-arrow\"></div>\n" + 
    " <div class=\"tooltip-inner\" ng-bind-html-unsafe=\"getToolTipHtml()\"></div>\n" + 
    "</div>\n" + 
    ""); 
}]); 

Poi, fare una funzione di collegamento per il 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 personalizzato il codice 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", 
      "<div class=\"popover {{placement}}\" ng-class=\"{ in: isOpen(), fade: animation() }\">\n" + 
      " <div class=\"arrow\"></div>\n" + 
      "\n" + 
      " <div class=\"popover-inner\">\n" + 
      "  <h3 class=\"popover-title\" ng-bind=\"title\" ng-show=\"title\"></h3>\n" + 
      "  <div class=\"popover-content\" ng-bind-html=\"content\"></div>\n" + 
      " </div>\n" + 
      "</div>\n" + 
      ""); 
     }]); 

    angular.module("template/popover/popover-html-unsafe.html", []).run(["$templateCache", function($templateCache) { 
     $templateCache.put("template/popover/popover-html-unsafe.html", 
      "<div class=\"popover {{placement}}\" ng-class=\"{ in: isOpen(), fade: animation() }\">\n" + 
      " <div class=\"arrow\"></div>\n" + 
      "\n" + 
      " <div class=\"popover-inner\">\n" + 
      "  <h3 class=\"popover-title\" ng-bind=\"title\" ng-show=\"title\"></h3>\n" + 
      "  <div class=\"popover-content\" ng-bind-html-unsafe=\"{{getPopoverHtml()}}\"></div>\n" + 
      " </div>\n" + 
      "</div>\n" + 
      ""); 
    }]); 

    angular.module("template/popover/popover-template.html", []).run(["$templateCache", function($templateCache) { 
    $templateCache.put("template/popover/popover-template.html", 
      "<div class=\"popover {{placement}}\" ng-class=\"{ in: isOpen(), fade: animation() }\">\n" + 
      " <div class=\"arrow\"></div>\n" + 
      "\n" + 
      " <div class=\"popover-inner\">\n" + 
      "  <h3 class=\"popover-title\" ng-bind=\"title\" ng-show=\"title\"></h3>\n" + 
      "  <div class=\"popover-content\" ng-include=\"getPopoverTemplate()\"></div>\n" + 
      " </div>\n" + 
      "</div>\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 tag body (questo è probabile applicabile per i suggerimenti troppo, sarà solo necessario modificare in base alle proprie esigenze):

<body data-ng-controller="AppController" data-dismiss-popovers> 
+0

Accordi ng to angular-ui's wiki, questa è la sintassi corretta. [http://angular-ui.github.io/bootstrap/#/tooltip](http://angular-ui.github.io/bootstrap/#/tooltip) ho provato tua, non ha funzionato. – Mencls

+0

Oh merda! Hai ragione, ho dimenticato, ho modificato bootstrap per supportarlo. Normalmente, vuole il contenuto reale. – aet

+0

Grazie per la risposta. Dove devo mettere la funzione di collegamento? – Mencls

6

ho creato direttiva personalizzato che consente di usare tooltips html per il bootstrap in modo molto semplice. Non c'è bisogno di sovrascrivere tutti i modelli:

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 = $('<div/>'); 
         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(); 
       } 
      }; 
     } 
    }; 
}]); 

Thats come lo chiami tu

<a va-tooltip="'tooltipContent.html'" tooltip-updater="item" tooltip-placement="bottom"> 
       <b><i>{{item.properties.length - propertyShowLimit + ' properties more...'}}</i></b> 
      </a> 

E modello può essere in questo modo:

<script id="tooltipContent.html" type="text/ng-template"> 
    <span ng-repeat="prop in item.properties> 
     <b>{{prop.name}}</b>: 
     <span ng-repeat="val in prop.values">{{val.value}}&nbsp;</span> 
     <br /> 
    </span> 
</script> 
+0

non ha funzionato per me ma è stata una grande idea;). – botero

4

V'è ora buit-in funzionalità modello: https://angular-ui.github.io/bootstrap/#tooltip

<a href="#" uib-tooltip-template="'myTooltipTemplate.html'">Custom template</a> 

<script type="text/ng-template" id="myTooltipTemplate.html"> 
    <span>Special Tooltip with <strong>markup</strong> and {{ dynamicTooltipText }}</span> 
</script> 
Problemi correlati