Ich möchte meiner AngularJS-Anwendung einige Dienstprogrammfunktionen hinzufügen. Beispielsweise:
$scope.isNotString = function (str) {
return (typeof str !== "string");
}
Ist dies der beste Weg, um sie als Service hinzuzufügen? Nach dem, was ich gelesen habe, kann ich dies tun, aber dann möchte ich diese in meinen HTML-Seiten verwenden. Ist es also immer noch möglich, wenn sie in einem Dienst sind? Zum Beispiel kann ich Folgendes verwenden:
<button data-ng-click="doSomething()"
data-ng-disabled="isNotString(abc)">Do Something
</button>
Kann mir jemand ein Beispiel geben, wie ich diese hinzufügen könnte. Sollte ich einen Service erstellen oder gibt es eine andere Möglichkeit, dies zu tun? Am wichtigsten ist, dass ich diese Dienstprogrammfunktionen in einer Datei und nicht mit einem anderen Teil der Hauptkonfiguration kombinieren möchte.
Ich verstehe, dass es einige Lösungen gibt, aber keine davon ist so klar.
Lösung 1 - Vorgeschlagen von Urban
$scope.doSomething = ServiceName.functionName;
Das Problem hier ist, dass ich 20 Funktionen und zehn Controller habe. Wenn ich das tun würde, würde es bedeuten, jedem Controller viel Code hinzuzufügen.
Lösung 2 - Vorgeschlagen von mir
var factory = {
Setup: function ($scope) {
$scope.isNotString = function (str) {
return (typeof str !== "string");
}
Dies hat den Nachteil, dass ich zu Beginn jedes Controllers einen oder mehrere dieser Setup-Aufrufe für jeden Dienst habe, der den $ -Bereich überschritten hat.
Lösung 3 - Vorgeschlagen von Urban
Die von urban vorgeschlagene Lösung zur Schaffung eines generischen Dienstes sieht gut aus. Hier ist meine Hauptkonfiguration:
var app = angular
.module('app', ['ngAnimate', 'ui.router', 'admin', 'home', 'questions', 'ngResource', 'LocalStorageModule'])
.config(['$locationProvider', '$sceProvider', '$stateProvider',
function ($locationProvider, $sceProvider, $stateProvider) {
$sceProvider.enabled(false);
$locationProvider.html5Mode(true);
Sollte ich den generischen Service hinzufügen und wie könnte ich das tun?
Antworten:
EDIT 7/1/15:
Ich habe diese Antwort vor ziemlich langer Zeit geschrieben und habe eine Weile nicht viel mit Angular Schritt gehalten, aber es scheint, als ob diese Antwort immer noch relativ beliebt ist, deshalb wollte ich darauf hinweisen, dass ein paar Punkte @nicolas Marken unten sind gut. Zum einen müssen Sie durch das Injizieren von $ rootScope und das Anhängen der Helfer diese nicht für jeden Controller hinzufügen. Außerdem stimme ich zu, dass wenn Sie das, was Sie hinzufügen, als Angular-Dienste ODER Filter betrachtet werden sollen, diese auf diese Weise in den Code übernommen werden sollten.
Außerdem stellt Angular ab der aktuellen Version 1.4.2 eine "Provider" -API zur Verfügung, die in Konfigurationsblöcke eingefügt werden darf. Weitere Informationen finden Sie in diesen Ressourcen:
https://docs.angularjs.org/guide/module#module-loading-dependencies
AngularJS-Abhängigkeitsinjektion des Werts innerhalb von module.config
Ich glaube nicht, dass ich die eigentlichen Codeblöcke unten aktualisieren werde, da ich Angular heutzutage nicht wirklich aktiv benutze und keine neue Antwort riskieren möchte, ohne mich sicher zu fühlen, dass sie tatsächlich dem neuen Besten entspricht Praktiken Methoden Ausübungen. Wenn jemand anderes Lust dazu hat, machen Sie es auf jeden Fall.
EDIT 2/3/14:
Nachdem ich darüber nachgedacht und einige der anderen Antworten gelesen habe, denke ich tatsächlich, dass ich eine Variation der von @Brent Washburne und @Amogh Talpallikar vorgebrachten Methode bevorzuge. Besonders wenn Sie nach Dienstprogrammen wie isNotString () oder ähnlichem suchen. Einer der klaren Vorteile hierbei ist, dass Sie sie außerhalb Ihres Winkelcodes wiederverwenden und innerhalb Ihrer Konfigurationsfunktion verwenden können (was Sie mit Diensten nicht tun können).
Abgesehen davon, wenn Sie nach einer generischen Möglichkeit suchen, die eigentlich wiederverwendeten Dienste wiederzuverwenden, ist die alte Antwort meiner Meinung nach immer noch eine gute.
Was ich jetzt tun würde, ist:
app.js:
controller.js:
Dann können Sie in Ihrem Teil verwenden:
Alte Antwort unten:
Es ist möglicherweise am besten, sie als Service einzuschließen. Wenn Sie sie auf mehreren Controllern wiederverwenden möchten, müssen Sie den Code nicht wiederholen, wenn Sie sie als Dienst einbeziehen.
Wenn Sie die Servicefunktionen in Ihrem HTML-Teil verwenden möchten, sollten Sie sie dem Bereich dieses Controllers hinzufügen:
$scope.doSomething = ServiceName.functionName;
Dann können Sie in Ihrem Teil verwenden:
Hier ist eine Möglichkeit, wie Sie alles organisiert und frei von zu viel Ärger halten können:
Trennen Sie Ihren Controller-, Service- und Routing-Code / Ihre Konfiguration in drei Dateien: controller.js, services.js und app.js. Das Modul der obersten Ebene ist "app", das app.controllers und app.services als Abhängigkeiten hat. Dann können app.controllers und app.services als Module in ihren eigenen Dateien deklariert werden. Diese Organisationsstruktur stammt nur aus Angular Seed :
app.js:
services.js:
controller.js:
Dann können Sie in Ihrem Teil verwenden:
Auf diese Weise fügen Sie jedem Controller nur eine Codezeile hinzu und können auf alle Dienstfunktionen zugreifen, wo immer auf diesen Bereich zugegriffen werden kann.
quelle
Als ich auf diesen alten Thread kam, wollte ich das betonen
1 °) Utility-Funktionen können (sollten?) Über module.run zum Rootscope hinzugefügt werden. Zu diesem Zweck muss kein bestimmter Root-Level-Controller instanziiert werden.
2 °) Wenn Sie Ihren Code in separate Module organisieren Sie Winkel verwenden sollen , Dienstleistungen oder Fabrik und sie dann in die Funktion des Laufblock, wie folgt übergeben injizieren:
3 °) Ich verstehe, dass Sie in Ansichten in den meisten Fällen diese Hilfsfunktionen benötigen, um eine Art Formatierung auf die von Ihnen angezeigten Zeichenfolgen anzuwenden. In diesem letzten Fall müssen Sie Winkelfilter verwenden
Und wenn Sie einige Hilfsmethoden auf niedriger Ebene in Winkeldienste oder Factory strukturiert haben, fügen Sie sie einfach in Ihren Filterkonstruktor ein:
Und aus Ihrer Sicht:
quelle
run
Zeit. Was ist mit der Konfigurationszeit? Brauchen wir da draußen keine Versorgungsunternehmen?Verstehe ich richtig, dass Sie nur einige Dienstprogrammmethoden definieren und in Vorlagen verfügbar machen möchten?
Sie müssen sie nicht jedem Controller hinzufügen. Definieren Sie einfach einen einzelnen Controller für alle Dienstprogrammmethoden und hängen Sie diesen Controller an <html> oder <body> an (mithilfe der ngController-Direktive). Alle anderen Controller, die Sie irgendwo unter <html> (dh irgendwo, Punkt) oder <body> (irgendwo außer <head>) anhängen, erben diesen $ scope und haben Zugriff auf diese Methoden.
quelle
<div class="main-container" ng-controller="UtilController as util">
dann in allen Innenansichten:<button ng-click="util.isNotString(abc)">
Der einfachste Weg, Dienstprogrammfunktionen hinzuzufügen, besteht darin, sie auf globaler Ebene zu belassen:
Der einfachste Weg, eine Dienstprogrammfunktion (zu einem Controller) hinzuzufügen, besteht darin, sie
$scope
wie folgt zuzuweisen :Dann können Sie es so nennen:
oder so:
BEARBEITEN:
Die ursprüngliche Frage ist, ob der beste Weg, eine Dienstprogrammfunktion hinzuzufügen, ein Dienst ist. Ich sage nein, wenn die Funktion einfach genug ist (wie das
isNotString()
Beispiel des OP).Der Vorteil des Schreibens eines Dienstes besteht darin, ihn zum Testen durch einen anderen (durch Injektion) zu ersetzen. Müssen Sie im Extremfall jede einzelne Utility-Funktion in Ihren Controller einspeisen?
In der Dokumentation heißt es, einfach das Verhalten im Controller zu definieren (wie
$scope.double
): http://docs.angularjs.org/guide/controllerquelle
Hier ist eine einfache, kompakte und leicht verständliche Methode, die ich verwende.
Fügen Sie zunächst einen Dienst in Ihr js ein.
Injizieren Sie dann in Ihrem Controller Ihr Hilfsobjekt und verwenden Sie eine der verfügbaren Funktionen wie folgt:
quelle
Sie können auch den ständigen Service als solchen nutzen. Wenn Sie die Funktion außerhalb des konstanten Aufrufs definieren, kann sie auch rekursiv sein.
quelle
Warum nicht die Controller-Vererbung verwenden? Alle im Bereich von HeaderCtrl definierten Methoden / Eigenschaften sind im Controller in ng-view verfügbar. Auf $ scope.servHelper kann in allen Ihren Controllern zugegriffen werden.
quelle