it-swarm.com.de

Wie erstelle ich ein AngularJS-UI bootstrap popover mit HTML-Inhalten?

Ich möchte ein Bootstrap-Popover mit einem Pre-Tag erstellen, das ein bestimmtes JSON-Objekt enthält. Die naive Umsetzung,

<span popover='<pre>{[ some_obj | json:"  " ]}</pre>'
      popover-trigger='mouseenter'>

der Inhalt wird ausgeblendet, bevor er in das Popup eingefügt wird. Wie kann ein Popover-Body mit HTML-Inhalt am besten angegeben werden?

43
Andrey Fedorov

[~ # ~] Update [~ # ~] :

Wie in this zu sehen, sollten Sie dies jetzt tun können, ohne die Standardvorlage zu überschreiben.

ORIGINAL:

Ab angular 1.2+ ng-bind-html-unsafe wurde entfernt. Sie sollten den Dienst $ sce verwenden. Referenz .

Hier ist ein Filter zum Erstellen von vertrauenswürdigem HTML.

MyApp.filter('unsafe', ['$sce', function ($sce) {
    return function (val) {
        return $sce.trustAsHtml(val);
    };
}]);

Hier ist das überschriebene Angular Bootstrap 0.11.2 Template, das von diesem Filter Gebrauch macht

// update popover template for binding unsafe html
angular.module("template/popover/popover.html", []).run(["$templateCache", function ($templateCache) {
    $templateCache.put("template/popover/popover.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-html=\"title | unsafe\" ng-show=\"title\"></h3>\n" +
      "      <div class=\"popover-content\"ng-bind-html=\"content | unsafe\"></div>\n" +
      "  </div>\n" +
      "</div>\n" +
      "");
}]);

EDIT: Hier ist eine Plunker Implementierung.

BEARBEITEN 2: Da diese Antwort immer wieder Treffer erhält, werde ich sie so gut wie möglich aktualisieren. Als Referenz Hier ist die Vorlage aus dem Angular-UI bootstrap Repo. Wenn sich dies ändert, erfordert die Überschreibungsvorlage übereinstimmende Updates und das Hinzufügen des ng-bind-html=\"title | unsafe\" und ng-bind-html=\"content | unsafe\" Attribute, um weiterarbeiten zu können.

Für aktualisierte Konversation überprüfen Sie das Problem hier .

71
Matthew.Lothian

Verwenden Sie die Popover-Vorlage Direktive

Wenn Sie eine Version von angular-ui gleich oder höher 0.13.0 verwenden, ist die beste Option die Verwendung die Direktive popover-template. So verwenden Sie es:

<button popover-template="'popover.html'">My HTML popover</button>

<script type="text/ng-template" id="popover.html">
    <div>
        Popover content
    </div>
</script>

NB: Vergessen Sie nicht die Anführungszeichen um den Vorlagennamen in popover-template="'popover.html'".

Siehe Demo-Plunker


Als Randnotiz ist es möglich, die Popover-Vorlage in einer dedizierten HTML-Datei zu externalisieren, anstatt sie wie oben in einem <script type="text/ng-template> - Element zu deklarieren.

Siehe zweiter Demo-Plunker

24

Ich habe eine Lösung für das Github-Projekt veröffentlicht: https://github.com/angular-ui/bootstrap/issues/52

Wenn Sie diese Funktionalität zu Ihrem Projekt hinzufügen möchten, finden Sie hier einen Patch.

Fügen Sie diese Anweisungen hinzu:

angular.module("XXX")
    .directive("popoverHtmlUnsafePopup", function () {
      return {
        restrict: "EA",
        replace: true,
        scope: { title: "@", content: "@", placement: "@", animation: "&", isOpen: "&" },
        templateUrl: "template/popover/popover-html-unsafe-popup.html"
      };
    })

    .directive("popoverHtmlUnsafe", [ "$tooltip", function ($tooltip) {
      return $tooltip("popoverHtmlUnsafe", "popover", "click");
    }]);

Und fügen Sie die Vorlage hinzu:

<div class="popover {{placement}}" ng-class="{ in: isOpen(), fade: animation() }">
  <div class="arrow"></div>

  <div class="popover-inner">
      <h3 class="popover-title" ng-bind="title" ng-show="title"></h3>
      <div class="popover-content" bind-html-unsafe="content"></div>
  </div>
</div>

Verwendung: <button popover-placement="top" popover-html-unsafe="On the <b>Top!</b>" class="btn btn-default">Top</button>

Sieh es dir auf plunkr an: http://plnkr.co/edit/VhYAD04ETQsJ2dY3Uum3?p=preview

9
user1067920

Sie müssen die Standard-Popover-Vorlage ändern, um anzugeben, dass Sie HTML-Inhalt zulassen möchten. Schau das popover-content div, jetzt erfolgt die Bindung an die Eigenschaft content, wodurch unsicheres HTML ermöglicht wird:

 angular.module("template/popover/popover.html", []).run(["$templateCache", function ($templateCache) {
        $templateCache.put("template/popover/popover.html",
            "<div class='popover {{placement}}' ng-class='{ in: isOpen(), fade: animation() }'>" + 
            "<div class='arrow'></div><div class='popover-inner'>" + 
            "<h3 class='popover-title' ng-bind='title' ng-show='title'></h3>" + 
            "<div class='popover-content' ng-bind-html-unsafe='content'></div>" +
            "<button class='btn btn-cancel' ng-click='manualHide()'>Cancel</button>" +
            "<button class='btn btn-apply' ng-click='manualHide()'>Apply</button></div></div>");
    }]);
6
Andres

Für all Ihre konventionellen Bootstrap popover -Anforderungen können Sie die folgende angular) - Anweisung verwenden. Sie beseitigt Unordnung in der HTML-Vorlage und ist sehr einfach zu handhaben verwenden.

Sie können das Ereignis title, content, placement, Einblenden/Ausblenden delay, trigger für Popover konfigurieren und festlegen, ob der Inhalt als behandelt werden soll html. Es verhindert auch das Überlaufen und Beschneiden von Inhalten.

Zugehöriger Plunker mit allen Codes hier http://plnkr.co/edit/MOqhJi

Screencap

imgur

Verwendung

<!-- HTML -->
<div ng-model="popup.content" popup="popup.options">Some element</div>

/* JavaScript */
this.popup = {
  content: 'Popup content here',
  options: {
    title: null,
    placement: 'right', 
    delay: { show: 800, hide: 100 }
  }
}; 

JavaScript

/**
 * Popup, a Bootstrap popover wrapper.
 *
 * Usage: 
 *  <div ng-model="model" popup="options"></div>
 * 
 * Remarks: 
 *  To prevent content overflow and clipping, use CSS
 *  .popover { Word-wrap: break-Word; }
 *  Popup without title and content will not be shown.
 *
 * @param {String}  ngModel           popup content
 * @param {Object}  options           popup options
 * @param {String}  options.title     title
 * @param {Boolean} options.html      content should be treated as html markup
 * @param {String}  options.placement placement (top, bottom, left or right)
 * @param {String}  options.trigger   trigger event, default is hover
 * @param {Object}  options.delay     milliseconds or { show:<ms>, hide:<ms> }
 */
app.directive('popup', function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    scope: {
      ngModel: '=',
      options: '=popup'
    },
    link: function(scope, element) {
      scope.$watch('ngModel', function(val) {
        element.attr('data-content', val);
      });

      var options = scope.options || {} ; 

      var title = options.title || null;
      var placement = options.placement || 'right';
      var html = options.html || false;
      var delay = options.delay ? angular.toJson(options.delay) : null;
      var trigger = options.trigger || 'hover';

      element.attr('title', title);
      element.attr('data-placement', placement);
      element.attr('data-html', html);
      element.attr('data-delay', delay);
      element.popover({ trigger: trigger });
    }
  };
});
6
Mikko Viitala

Siehe https://github.com/jbruni/bootstrap-bower-jbruni , mit dem eine Popover-Vorlage verwendet werden kann

3
Thierry

Das folgende CSS-Styling scheint das getan zu haben, was ich in meinem speziellen Fall wollte:

.popover-content {
  white-space: pre;
  font-family: monospace;
}

Die allgemeine Frage bleibt offen.

1
Andrey Fedorov