Können Sie bestimmte Vorlagen in AngularUI Bootstrap überschreiben?

88

Ich bin gespannt, ob es eine Möglichkeit gibt, einzelne, spezifische Vorlagen aus der Datei ui-bootstrap-tpls zu überschreiben. Die überwiegende Mehrheit der Standardvorlagen entspricht meinen Anforderungen, aber es gibt einige spezifische Vorlagen, die ich ersetzen möchte, ohne den gesamten Prozess des Erfassens aller Standardvorlagen und der Verkabelung mit der Nicht-TPLS-Version durchlaufen zu müssen.

Jeremy Privett
quelle
1
Ich habe auch festgestellt, dass ich den $modalService dekoriert habe , um mehr Konfigurierbarkeit zu erzielen, ohne (hoffentlich) zu viel Wartungsaufwand zu verursachen. $provide.decorator('$modal'... In meinem Fall wollte ich das modalWindowElement nicht rendern . Je. Ich habe es einfach nicht benutzt und das war das Beste, was ich mir einfallen lassen konnte. Ich würde gerne einen besseren Weg hören, wenn jemand es hat.
Körper

Antworten:

123

Ja, Direktiven von http://angular-ui.github.io/bootstrap sind in hohem Maße anpassbar und es ist einfach, eine der Vorlagen zu überschreiben (und sich für andere Direktiven weiterhin auf die Standardvorlagen zu verlassen).

Es reicht aus, sie zu füttern $templateCache, entweder direkt (wie in der ui-bootstrap-tplsDatei) oder - wahrscheinlich einfacher - eine Vorlage mithilfe der <script>Direktive ( doc ) zu überschreiben .

Ein konstruiertes Beispiel , wo ich alert die Vorlage Swap bin Wechsel xfür Closeunten dargestellt:

<!doctype html>
<html ng-app="plunker">
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>
    <script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.4.0.js"></script>
    <script src="example.js"></script>
    <link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">

    <script id="template/alert/alert.html" type="text/ng-template">
      <div class='alert' ng-class='type && "alert-" + type'>
          <button ng-show='closeable' type='button' class='close' ng-click='close()'>Close</button>
          <div ng-transclude></div>
      </div>
    </script>
  </head>

  <body>
    <div ng-controller="AlertDemoCtrl">
      <alert ng-repeat="alert in alerts" type="alert.type" close="closeAlert($index)">                     
        {{alert.msg}}
      </alert>
      <button class='btn' ng-click="addAlert()">Add Alert</button>
    </div>
  </body>
</html>

Live-Plunker: http://plnkr.co/edit/gyjVMBxa3fToYTFJtnij?p=preview

pkozlowski.opensource
quelle
19
Ich mag diese Antwort. Ich mag es einfach nicht, dass es nicht auf der Dokumentationsseite von Angular UI enthalten ist, und ich habe eine ganze Weile gebraucht, um herauszufinden, wie man etwas so Einfaches wie das Anzeigen eines Modals macht.
Tri Vuong
2
@ BruceBanner-Dokumentation und solide Arbeitsbeispiele sind die beiden größten Nachteile der Angular-Benutzeroberfläche. Das Projekt ist großartig, aber es braucht etwas süße, zarte Entwicklerliebe.
Robin van Baalen
1
@RobinvanBaalen Dies ist eine Angular-Js-Funktion (nicht Angular-UI), die bereits in den offiziellen Dokumenten von
Angular
Bitte überprüfen Sie die Antwort von @JcT zu $ ​​supply.decorator, da dies der Angular-Weg (in diesem Fall der gute Weg) ist, um Direktivenvorlagen zu überschreiben. Und es ist ziemlich einfach. Das Hinzufügen / Überschreiben einer Vorlage zu $ ​​templateCache ist nicht die beste Vorgehensweise.
John Bernardsson
@ John Ich bin mir nicht sicher, woher du Dinge bekommst "das ist der Angular-Weg (der gute Weg in diesem Fall)" und "nur das Hinzufügen / Überschreiben einer Vorlage zu $ ​​templateCache ist nicht wirklich die beste Vorgehensweise", aber als eine von Angular- UI und Winkelpfleger Ich kann Ihnen versichern, dass das Überschreiben von Vorlagen nichts auszusetzen hat. Es sei denn, Sie haben bestimmte Probleme zu teilen ...
pkozlowski.opensource
79

Verwenden von $provide.decorator

Durch die Verwendung $providezum Dekorieren der Direktive wird vermieden, dass direkt damit herumgespielt werden muss $templateCache.

Erstellen Sie stattdessen Ihre externe HTML-Vorlage wie gewohnt mit einem beliebigen Namen und überschreiben Sie dann die Anweisungen, templateUrlum darauf zu verweisen.

angular.module('plunker', ['ui.bootstrap'])
  .config(['$provide', Decorate]);

  function Decorate($provide) {
    $provide.decorator('alertDirective', function($delegate) {
      var directive = $delegate[0];

      directive.templateUrl = "alertOverride.tpl.html";

      return $delegate;
    });
  }

Fork von pkozlowski.opensource ‚s plunkr: http://plnkr.co/edit/RE9AvUwEmKmAzem9mfpI?p=preview

(Beachten Sie, dass Sie das Suffix 'Direktive' an den Namen der Direktive anhängen müssen, die Sie dekorieren möchten. Oben dekorieren wir die alertDirektive von UI Bootstrap , daher verwenden wir den Namen alertDirective.)

Da Sie häufig mehr tun möchten, als nur die zu überschreiben templateUrl, bietet dies einen guten Ausgangspunkt, um die Direktive weiter zu erweitern, beispielsweise durch Überschreiben / Umschließen der Verknüpfungs- oder Kompilierungsfunktion ( zum Beispiel ).

JcT
quelle
9
Dies ist die richtige Lösung und folgt den Best Practices für Winkel. Sie sollten NIEMALS Zeichenfolgen verwenden, um HTML zu erstellen, und Sie sollten es auch nicht explizit in die Datei index.html aufnehmen müssen, in die Sie Skripte von Drittanbietern einfügen. Danke @JcT!
TommyMac
2
Hallo, ist alertDirectiveein Schlüsselwort? Wenn ja, wofür lautet das Schlüsselwort Tabs? Ich versuche, ähnliche Dinge auf Registerkarten zu tun, aber ich habe die alert.js durchgesehen und sehe nicht, wo sie sich alertDirectivedort befanden .
Codenamezero
4
Das anglejs $compileProviderfügt dem Namen Ihrer Direktive bei der Registrierung ein Suffix 'Direktive' hinzu ( $filterProviderähnlich wie bei einem Suffix 'Filter'). Für die meisten Zwecke ist dies unsichtbar, aber beim Dekorieren müssen Sie dieses Suffix an die Direktive anhängen, auf die Sie abzielen möchten. Zum Beispiel tabDirectiveoder tabsetDirectiveusw. Nicht genau klar dokumentiert, wo ich sie finden konnte, aber hier ist ein Hinweis auf das ähnliche Verhalten $filterProviderzumindest für: docs.angularjs.org/api/ng/provider/$filterProvider
JcT
2
Vielen Dank @JcT, eine tolle Antwort. Dies ist der richtige Weg. Und, wie Sie sagen, ein guter Ausgangspunkt für die "Dekoration" von Richtlinien Dritter :)
John Bernardsson
1
@ValeraTumash: Entschuldigung für die späte Antwort. Ja, ich denke, deine Konfiguration wird überfordert sein. Ab Angular v1.3 können Sie jedoch ein function(element, attributes)TemplateUrl bereitstellen . Sie können dies für ein dynamisches Verhalten verwenden (geben Sie die ursprüngliche templateUrl-Funktion oder Ihre eigene URL-Zeichenfolge zurück, abhängig von einem Attribut usw.). Ui.bootstrap verwendet jetzt jedoch auch dieselbe Funktionalität, mit der Sie ein template-urlAttribut für eine Direktive angeben können. Sie können dies also möglicherweise auch verwenden, wenn Sie den Vorlagenpfad direkt über das Direktivenelementattribut bereitstellen möchten .
JcT
27

Die Antwort von pkozlowski.opensource ist wirklich nützlich und hat mir sehr geholfen! Ich habe es in meinem Zustand so angepasst, dass eine einzige Datei alle meine Winkelvorlagenüberschreibungen definiert, und das externe JS geladen, um die Nutzlastgröße gering zu halten.

Gehen Sie dazu zum Ende der eckigen UI-Bootstrap-Quell-JS-Datei (z. B. ui-bootstrap-tpls-0.6.0.js) und suchen Sie die Vorlage, an der Sie interessiert sind. Kopieren Sie den gesamten Block, der die Vorlage definiert, und fügen Sie ihn in Ihre überschriebene JS-Datei ein.

z.B

angular.module("template/alert/alert.html", []).run(["$templateCache", function($templateCache) {
  $templateCache.put("template/alert/alert.html",
     "      <div class='alert' ng-class='type && \"alert-\" + type'>\n" +
     "          <button ng-show='closeable' type='button' class='close' ng-click='close()'>Close</button>\n" +
     "          <div ng-transclude></div>\n" +
     "      </div>");
}]);

Fügen Sie dann einfach Ihre Overrides-Datei nach dem UI-Bootstrap hinzu und Sie erzielen das gleiche Ergebnis.

Gegabelte Version von pkozlowski.opensources Plunk http://plnkr.co/edit/iF5xw2YTrQ0IAalAYiAg?p=preview

Matt Byrne
quelle
1
Ich benutze das gleiche Muster, und obwohl es funktioniert; Ich wünschte wirklich, es gäbe einen besseren Weg. Ich denke, ich würde die Konfiguration dem Clobbering vorziehen.
Körper
7

Sie können template-url="/app/.../_something.template.html"die aktuelle Vorlage für diese Anweisung überschreiben.

(Funktioniert mindestens in Accordion Bootstrap.)

Purpur
quelle