Ist es sinnvoll, Require.js mit Angular.js zu verwenden? [geschlossen]


443

Ich bin ein Neuling bei Angular.js und versuche zu verstehen, wie es sich von Backbone.js unterscheidet ... Wir haben unsere Paketabhängigkeiten mit Require.js verwaltet, während wir Backbone verwendet haben. Ist es sinnvoll, dasselbe mit Angular.js zu tun?


Ein weiterer Blog und Saatgutprojekt: startersquad.com/blog/angularjs-requirejs
Iwein

19
Nein - Verwenden Sie nicht require.js ODER browserify mit Angular.JS. Es ist einfach nicht erforderlich, dies zu tun. - AngularJS verfügt über ein Modulsystem, und die Verwendung eines anderen Modulsystems darüber macht Ihnen das Leben unnötig schwer. Ich habe die Antworten in diesem Thread befolgt und zu viele Stunden mit etwas verschwendet, das völlig unnötig war. Bitte lesen Sie diesen Artikel, der erklärt, warum nicht: medium.com/@dickeyxxx/…
VitalyB

Lesen Sie dies, um den Unterschied zwischen eckigen und erforderlichen Modulen zu verstehen. Juristr.com/blog/2014/07/lazy-angular-modules
pilavdzice

1
Hier ist ein großartiges Video, das erklärt, warum es eine gute Idee ist und zeigt, wie man requireJS mit angleJS verwendet. youtube.com/watch?v=4yulGISBF8w#t=142
gskalinskii

2
@VitalyB Schöner Artikel! Ich bevorzuge das Laden von Anwendungen in kleinen Stücken. Es wird nichts früh genug kosten . Verdammt, es kostet mich momentan nichts.
Dsign

Antworten:


224

Ja, es ist sinnvoll, angular.jszusammen mit require.jsdem Sie require.jsfür die Modularisierung von Komponenten verwenden können.

Es gibt ein Seed-Projekt, das verwendet both angular.js and require.js.


108
Das oben erwähnte Seed-Projekt wurde seit einem Jahr nicht mehr berührt, daher habe ich ein neues mit den neuesten AngularJS und RequireJS erstellt, das die testakelgetriebenen Tests voll unterstützt.
Tnajdek

2
@tnajdek, ich habe den Link in Anshus Antwort aktualisiert, um auf den von Ihnen vorgeschlagenen zu verweisen.
David Rivers

7
Beachten Sie, dass keines dieser Startprojekte vom Angular-Team unterstützt wird. Require ist ein Muster, das in anderen Kontexten sinnvoller war, und es ist meiner Meinung nach keine bewährte Methode, es in Angular zu integrieren.
XML

2
Das O'Reilly AngularJS-Buch von Brad Green & Shyam Seshadri (veröffentlicht im April dieses Jahres) empfiehlt außerdem, RequireJS zu Beginn des Wachstums eines Angular-Projekts hinzuzufügen, und enthält Einzelheiten ganz klar.
Bjorke

1
Ich würde viel lieber alles zur Build-Zeit machen 1. browserify.org 2. npmjs.org/package/gulp-angular-filesort
A-Dubb

150

Um noch einmal zu sagen, was meiner Meinung nach die Frage des OP wirklich ist:

Wenn ich eine Anwendung hauptsächlich in Angular 1.x erstelle und dies (implizit) im Zeitalter von Grunt / Gulp / Broccoli und Bower / NPM tue und möglicherweise einige zusätzliche Bibliotheksabhängigkeiten habe, muss Require klar und spezifisch sein Wert über das hinaus, was ich durch die Verwendung von Angular ohne Anforderung erhalte?

Oder anders ausgedrückt:

"Muss Vanilla Angular das grundlegende Laden von Angular-Komponenten effektiv verwalten, wenn ich andere Möglichkeiten habe, das grundlegende Laden von Skripten zu handhaben? "

Und ich glaube, die grundlegende Antwort darauf lautet: "Es sei denn, Sie haben etwas anderes im Gange und / oder können keine neueren, moderneren Tools verwenden."

Lassen Sie uns gleich zu Beginn klar sein: RequireJS ist ein großartiges Tool, das einige sehr wichtige Probleme gelöst und uns auf den Weg zu skalierbareren, professionelleren Javascript-Anwendungen gebracht hat. Wichtig ist, dass es das erste Mal war, dass viele Menschen auf das Konzept der Modularisierung und des Ausstiegs aus dem globalen Geltungsbereich stießen. Wenn Sie also eine Javascript-Anwendung erstellen möchten, die skaliert werden muss, sind Require und das AMD-Muster keine schlechten Werkzeuge dafür.

Aber gibt es etwas Besonderes an Angular, das Require / AMD besonders gut passt? Nein. Angular bietet Ihnen ein eigenes Modularisierungs- und Kapselungsmuster, das die grundlegenden Modularisierungsfunktionen von AMD in vielerlei Hinsicht überflüssig macht. Die Integration von Angular-Modulen in das AMD-Muster ist nicht unmöglich, aber ein bisschen ... pingelig. Sie werden auf jeden Fall Zeit damit verbringen, die beiden Muster gut zu integrieren.

Für eine Perspektive aus dem Angular-Team selbst gibt es diese von Brian Ford, Autor des Angular Batarang und jetzt Mitglied des Angular-Kernteams:

Ich empfehle nicht, RequireJS mit AngularJS zu verwenden. Obwohl es sicherlich möglich ist, habe ich keinen Fall gesehen, in dem RequireJS in der Praxis von Vorteil war.

Zur sehr spezifischen Frage von AngularJS: Angular und Require / AMD sind orthogonal und stellenweise überlappend. Sie können sie zusammen verwenden, aber es gibt keinen Grund, der speziell mit der Natur / den Mustern von Angular selbst zusammenhängt.

Aber was ist mit der grundlegenden Verwaltung interner und externer Abhängigkeiten für skalierbare Javascript-Anwendungen? Muss Require dort nicht etwas wirklich Kritisches für mich tun?

Ich empfehle Bower und NPM und insbesondere NPM. Ich versuche nicht, einen heiligen Krieg über die komparativen Vorteile dieser Werkzeuge zu beginnen. Ich möchte nur sagen: Es gibt andere Möglichkeiten, diese Katze zu häuten, und diese Möglichkeiten sind möglicherweise sogar besser als AMD / Require. (Sie haben Ende 2015 sicherlich eine viel populärere Dynamik, insbesondere NPM, kombiniert mit ES6- oder CommonJS-Modulen. Siehe verwandte SO-Frage .)

Was ist mit Lazy-Loading?

Beachten Sie, dass das verzögerte Laden und das verzögerte Herunterladen unterschiedlich sind. Angulars verzögertes Laden bedeutet nicht, dass Sie sie direkt vom Server abrufen. In einer Anwendung im Yeoman-Stil mit Javascript-Automatisierung verketten und minimieren Sie den gesamten Shebang in einer einzigen Datei. Sie sind vorhanden, werden aber erst ausgeführt / instanziiert, wenn sie benötigt werden. Die Geschwindigkeits- und Bandbreitenverbesserungen, die Sie dadurch erzielen, überwiegen bei weitem alle angeblichen Verbesserungen, die durch das verzögerte Herunterladen eines bestimmten 20-Zeilen-Controllers entstehen. Tatsächlich wird die verschwendete Netzwerklatenz und der Übertragungsaufwand für diesen Controller eine Größenordnung größer sein als die Größe des Controllers selbst.

Angenommen, Sie müssen wirklich faul herunterladen, möglicherweise für selten verwendete Teile Ihrer Anwendung, z. B. eine Administrationsoberfläche. Das ist ein sehr legitimer Fall. Require kann das in der Tat für Sie tun. Aber es gibt auch viele andere , möglicherweise mehr flexible Optionen , die das Gleiche erreichen. Und Angular 2.0 wird sich anscheinend darum kümmern, in den Router integriert . ( Details .)

Aber was ist mit der Entwicklung auf meiner lokalen Entwicklerbox?

Wie kann ich alle meine Dutzende / Hunderte von Skriptdateien laden, ohne sie alle manuell an index.html anhängen zu müssen?

Schauen Sie sich die Untergeneratoren in Yeomans Generator-Winkel an, oder die Automatisierungsmuster, die in Generator-Schluck-Winkel enthalten sind , oder die Standard-Webpack-Automatisierung für React. Diese bieten Ihnen eine saubere, skalierbare Möglichkeit, entweder die Dateien zum Zeitpunkt des Gerüstbaus automatisch anzuhängen oder sie alle automatisch abzurufen, wenn sie in bestimmten Ordnern vorhanden sind / bestimmten Glob-Mustern entsprechen. Sie müssen nie wieder über das Laden von Skripten nachdenken, wenn Sie die letzteren Optionen haben.

Endeffekt?

Require ist für bestimmte Dinge ein großartiges Werkzeug. Aber gehen Sie mit dem Getreide, wann immer es möglich ist, und trennen Sie Ihre Bedenken, wann immer dies möglich ist. Lassen Sie Angular sich Gedanken über Angulars eigenes Modularisierungsmuster machen und erwägen Sie, ES6-Module oder CommonJS als allgemeines Modularisierungsmuster zu verwenden. Lassen Sie moderne Automatisierungstools sich um das Laden von Skripten und das Abhängigkeitsmanagement kümmern. Und kümmern Sie sich um das asynchrone Faul-Laden auf granulare Weise, anstatt es mit den beiden anderen Anliegen zu verwechseln.

Wenn Sie jedoch Angular-Apps entwickeln, Node jedoch aus irgendeinem Grund nicht auf Ihrem Computer installieren können, um Javascript-Automatisierungstools zu verwenden, ist Require möglicherweise eine gute alternative Lösung. Und ich habe wirklich aufwändige Setups gesehen, bei denen Leute Angular-Komponenten dynamisch laden möchten, die jeweils ihre eigenen Abhängigkeiten deklarieren oder so. Und während ich wahrscheinlich versuchen würde, dieses Problem auf andere Weise zu lösen, kann ich die Vorzüge der Idee für diese ganz besondere Situation erkennen.

Aber ansonsten ... wenn Sie mit einer neuen Angular-Anwendung und der Flexibilität beginnen, eine moderne Automatisierungsumgebung zu erstellen, haben Sie viele andere, flexiblere und modernere Optionen.

(Wird wiederholt aktualisiert, um mit der sich entwickelnden JS-Szene Schritt zu halten.)


1
Das NG-Boilerplate-Seed-Projekt ( github.com/ngbp/ngbp ) erstellt auch eine einseitige Webanwendung mit einer js-Datei. Durch die Verwendung eines HTML5-Manifests wird sichergestellt, dass diese Datei nur einmal pro Version geladen wird.
Federico Elles

2
Wie immer hängt <i> davon ab </ i>. Viele Menschen verwenden Require für ihre gesamte Architektur und müssen Angular in dieses Ökosystem integrieren. Dies ist eine ganz andere Situation als wenn Sie Apps isoliert erstellen.
Dave Nichol

2
Einverstanden. Aber der Kern des OP scheint zu sein: "Wenn ich eine Anwendung hauptsächlich in Angular erstelle und dies (implizit) in der Ära von Grunt tue und möglicherweise ein paar zusätzliche Bibliotheksabhängigkeiten habe, fügt Require darüber hinaus einen klaren, spezifischen Wert hinzu Was bekomme ich mit Angular ohne Require? " Und ich glaube, die Antwort lautet: Nein. Wenn Sie eine große Anwendung mit 40 externen Abhängigkeiten haben oder Ihre CI-Umgebung nicht kontrollieren können oder Ihr Chef Require liebt oder Require liebt oder Angular nur ein Teil einer größeren Anwendung usw. usw. ist, dann YMMV.
XML

1
Aber da er diese Fragen nicht zu stellen scheint und lediglich den alternativen Kontext einer Backbone-App erwähnt, scheint er zu fragen: "Muss Vanilla Angular erforderlich sein, um ihre Komponenten effektiv zu verwalten?" Und die Antwort lautet: "Nicht, wenn nicht noch etwas los ist." Diese Frage stand auch kurz vor der Javascript CI-Bewegung, bei der wir viel bessere Möglichkeiten haben, mit dem grundlegenden physischen "Laden von Skripten" umzugehen. Wenn Sie dieses Problem gelöst haben, geht es bei Require im Wesentlichen um Abhängigkeitsanpassung und Kapselung. Angular erledigt beides für Sie.
XML

Google verwendet das verzögerte Laden in einigen seiner AngularJS-Projekte, da der Benutzer andernfalls beim Laden der ersten Seite 24 MB Dateien herunterladen würde (und dies bei Dateien, die hässlich und verkettet sind). Ja, in komplexen Anwendungen müssen nicht alle Abschnitte verkettet werden. Wenn es Abschnitte gibt, wird der Benutzer nicht bei jedem Besuch geöffnet.
ngDeveloper

136

Ja, das macht Sinn.

Winkelmodule versuchen nicht, das Problem der Reihenfolge beim Laden von Skripten oder des verzögerten Abrufs von Skripten zu lösen. Diese Ziele sind orthogonal und beide Modulsysteme können nebeneinander leben und ihre Ziele erfüllen.

Quelle: Offizielle Website von Angular JS


6
Wenn Sie ein Modul pro JS-Datei verwenden, können Sie Ihr Winkelmodul in beliebiger Reihenfolge laden. Wenn Sie jedoch beispielsweise verschiedene Dienste in verschiedene js-Dateien einfügen möchten, diese aber an dasselbe Winkelmodul anhängen möchten, müssen Sie die Moduldeklaration vor der Dienstdeklaration laden. Das ist also eine Architekturentscheidung.
Matohawk

@Tiago: Bitte geben Sie einen Link zu dem Ort an, von dem Sie dies bezogen haben. Ich kann es nirgendwo finden. Ich vermute, dass es aus einer früheren Version der Angular-Dokumente stammt, bevor sich Angulars Muster ebenfalls etabliert hatten und bevor klar wurde, dass die Vermeidung von Require zumindest für Angular-Komponenten erhebliche Vorteile bietet.
XML

@XMLilley: Können Sie einen Link bereitstellen, der die Vorteile der Vermeidung von Require bei Verwendung von Angular erläutert? Ich entscheide, ob Require in meinem Projekt verwendet werden soll oder nicht, und das scheint hilfreich zu sein.
Trevor

1
Ich war mir in meiner Sprache hier nicht sicher: Es hat erhebliche Vorteile, Angulars eingebaute Modullader zu nutzen und mit der Körnung von Angular-Mustern zu arbeiten. Die Frage ist nicht , ob zu vermeiden erforderlich, sondern vielmehr , ob es Wert eine zusätzliche Ebene der Komplexität hinzuzufügen. Es ist klar, dass die in Angular integrierten Muster die Notwendigkeit des Ladens von Angulars eigenen Modulen handlich und elegant erfüllen. Wenn Require einen Zweck zum Laden von Modulen außerhalb des Angular-Kontexts erfüllt, ist dies auch der Fall. Die Verwendung von Require for Angular ist jedoch irrelevant.
XML

6
@XMLilley Angular gibt Ihnen lediglich eine Abhängigkeitsinjektion. Das eigentliche Laden des Moduls liegt in Ihrer Verantwortung. Sie können dies entweder tun, indem Sie ein Skript-Tag hinzufügen, ein Build-Skript haben oder requirejs verwenden. Das Angulars-Modulsystem hat hierzu keine Meinung.
Gillesruppert

57

Dies ist meiner Meinung nach eine subjektive Frage, daher werde ich meine subjektive Meinung abgeben.

Angular verfügt über einen integrierten Modularisierungsmechanismus. Wenn Sie Ihre App erstellen, müssen Sie zunächst etwas tun

var app = angular.module("myApp");

und dann

app.directive(...);

app.controller(...);

app.service(...);

Wenn Sie sich das Angular-Seed ansehen, das eine nette Starter-App für Angular ist, haben sie die Anweisungen, Dienste, Controller usw. in verschiedene Module aufgeteilt und diese Module dann als Abhängigkeiten von Ihrer Haupt-App geladen.

Etwas wie :

var app = angular.module("myApp",["Directives","Controllers","Services"];

Angular lädt auch faul diese Module (in den Speicher), nicht ihre Skriptdateien.

In Bezug auf das verzögerte Laden von Skriptdateien wäre es ein Overkill, um ehrlich zu sein, es sei denn, Sie schreiben etwas extrem Großes, da Winkel von Natur aus die Menge an Code reduzieren, die Sie schreiben. Eine typische App, die in den meisten anderen Frameworks geschrieben wurde, könnte eine Reduzierung des LOC um etwa 30-50% erwarten, wenn sie in einem Winkel geschrieben wird.


5
In der Tat ist es besser, Dienste in Angular.js zu konfigurieren, als Module mit Require.js zu laden. Dies macht es einfacher, mit dem $ scope und den Diensten zu spielen, da ich mit Socket.io
Marco Godínez

33

Die Verwendung von RequireJS mit AngularJS ist sinnvoll, aber nur, wenn Sie verstehen, wie jeder von ihnen in Bezug auf die Abhängigkeitsinjektion funktioniert , da beide zwar Abhängigkeiten injizieren, aber sehr unterschiedliche Dinge injizieren.

AngularJS verfügt über ein eigenes Abhängigkeitssystem, mit dem Sie AngularJS-Module in ein neu erstelltes Modul einfügen können, um Implementierungen wiederzuverwenden. Angenommen, Sie haben ein "erstes" Modul erstellt, das einen AngularJS-Filter "greet" implementiert:

angular
  .module('first', [])
  .filter('greet', function() {
    return function(name) {
      return 'Hello, ' + name + '!';
    }
  });

Angenommen, Sie möchten den "Greet" -Filter in einem anderen Modul namens "second" verwenden, das einen "Goodbye" -Filter implementiert. Sie können dies tun, indem Sie das "erste" Modul in das "zweite" Modul einfügen:

angular
  .module('second', ['first'])
  .filter('goodbye', function() {
    return function(name) {
      return 'Good bye, ' + name + '!';
    }
  });

Damit dies ohne RequireJS korrekt funktioniert, müssen Sie sicherstellen, dass das "erste" AngularJS-Modul auf der Seite geladen ist, bevor Sie das "zweite" AngularJS-Modul erstellen. Zitierdokumentation:

Abhängig von einem Modul bedeutet dies, dass das erforderliche Modul geladen werden muss, bevor das erforderliche Modul geladen wird.

In diesem Sinne kann RequireJS Ihnen hier helfen, da RequireJS eine saubere Möglichkeit bietet, Skripte in die Seite einzufügen, mit der Sie Skriptabhängigkeiten untereinander organisieren können.

Zurück zu den "ersten" und "zweiten" AngularJS-Modulen: Gehen Sie wie folgt vor, indem Sie RequireJS verwenden, um die Module in verschiedenen Dateien zu trennen und das Laden von Skriptabhängigkeiten zu nutzen:

// firstModule.js file
define(['angular'], function(angular) {
  angular
    .module('first', [])
    .filter('greet', function() {
      return function(name) {
        return 'Hello, ' + name + '!';
      }
    });
});
// secondModule.js file
define(['angular', 'firstModule'], function(angular) {
  angular
    .module('second', ['first'])
    .filter('goodbye', function() {
      return function(name) {
        return 'Good bye, ' + name + '!';
      }
    });
});

Sie können sehen, dass wir von der zu injizierenden "firstModule" -Datei abhängig sind, bevor der Inhalt des RequireJS-Rückrufs ausgeführt werden kann, für den das "erste" AngularJS-Modul geladen werden muss, um das "zweite" AngularJS-Modul zu erstellen.

Randnotiz: Um AngularJS in der RequireJS-Rückruffunktion zu verwenden, muss "Angular" in die Dateien "firstModule" und "secondModule" als Abhängigkeit eingefügt werden. In der RequireJS-Konfiguration muss es konfiguriert werden, um "Angular" dem Bibliothekscode zuzuordnen. Möglicherweise wird AngularJS auch auf herkömmliche Weise auf die Seite geladen (Skript-Tag), obwohl die Vorteile von RequireJS beeinträchtigt sind.

Weitere Informationen zur RequireJS-Unterstützung von AngularJS Core ab Version 2.0 finden Sie in meinem Blogbeitrag.

Basierend auf meinem Blog-Beitrag "RequireJS mit AngularJS verstehen" , hier ist der Link .


2
Wenn Sie einen Link einfügen, ist es am besten, den Inhalt des Links hier auf Stack Overflow zusammenzufassen. Sollte Ihr Link jemals unterbrochen werden, was Links im Internet tun, wäre Ihre Antwort hier für zukünftige Besucher nutzlos. Betrachten Sie eine Bearbeitung , um eine Zusammenfassung zu erstellen und diesen Beitrag zu verbessern. Viel Glück!
jmort253

3
Los geht's, danke jmort253.
Leog

Vielen Dank, dass Sie diese Änderungen vorgenommen und erklärt haben, wie RequireJS beim Verwalten der Abhängigkeiten helfen kann, um Probleme mit Angular zu vermeiden, die versuchen, etwas zu laden, das noch nicht vorhanden ist.
jmort253

Ich stimme voll und ganz zu, es ist am besten, diesen Ansatz für große Anwendungen zu verwenden, wenn Ihre Anwendung nicht mehrere <script> -Tags enthält.
I.Tyger

21

Wie @ganaraj erwähnte, hat AngularJS im Kern eine Abhängigkeitsinjektion. Beim Erstellen von Spielzeugsaatgutanwendungen mit und ohne RequireJS stellte ich persönlich fest, dass RequireJS für die meisten Anwendungsfälle wahrscheinlich übertrieben war.

Das bedeutet nicht, dass RequireJS nicht nützlich ist, um Skripte zu laden und Ihre Codebasis während der Entwicklung sauber zu halten. Durch die Kombination des r.js-Optimierers ( https://github.com/jrburke/r.js ) mit Mandel ( https://github.com/jrburke/almond ) kann eine sehr schlanke Story zum Laden von Skripten erstellt werden. Da die Funktionen für das Abhängigkeitsmanagement bei Angular im Kern Ihrer Anwendung nicht so wichtig sind, können Sie auch andere clientseitige (HeadJS, LABjs, ...) oder sogar serverseitige (MVC4 Bundler, ...) Skriptladelösungen bewerten für Ihre spezielle Anwendung.


17

Ja, speziell für sehr große SPA.

In einigen Szenarien ist RequireJS ein Muss. Zum Beispiel entwickle ich PhoneGap-Anwendungen mit AngularJS, das auch die Google Map API verwendet. Ohne AMD Loader wie RequireJS stürzt die App beim Start einfach ab, wenn sie offline ist, da sie die Google Map API-Skripte nicht als Quelle verwenden kann. Ein AMD-Lader gibt mir die Möglichkeit, dem Benutzer eine Fehlermeldung anzuzeigen.

Die Integration zwischen AngularJS und RequireJS ist jedoch etwas schwierig. Ich habe angleAMD erstellt, um dies zu einem weniger schmerzhaften Prozess zu machen:

http://marcoslin.github.io/angularAMD/




7

Ja, es ist sinnvoll, requireJS mit Angular zu verwenden. Ich habe mehrere Tage damit verbracht, verschiedene technische Lösungen zu testen.

Ich habe mit RequireJS auf der Serverseite einen Angular Seed erstellt. Sehr einfach. Ich verwende die SHIM-Notation für kein AMD-Modul und nicht für AMD, da ich denke, dass es sehr schwierig ist, mit zwei verschiedenen Abhängigkeitsinjektionssystemen umzugehen.

Ich verwende grunt und r.js, um js-Dateien auf dem Server zu verketten. Dies hängt von der SHIM-Konfigurationsdatei (Abhängigkeitsdatei) ab. Ich verweise also nur auf eine js-Datei in meiner App.

Weitere Informationen finden Sie auf meinem Github Angular Seed: https://github.com/matohawk/angular-seed-requirejs


3

Ich würde die Verwendung von Require.js vermeiden. Apps, die ich gesehen habe, führen dazu, dass mehrere Arten von Modulmusterarchitekturen durcheinander gebracht werden. AMD, Revealing, verschiedene IIFE-Varianten usw. Es gibt andere Möglichkeiten, bei Bedarf zu laden, wie den loadOnDemand Angular-Mod . Das Hinzufügen anderer Dinge füllt Ihren Code nur mit Cruft und erzeugt ein niedriges Signal-Rausch-Verhältnis und macht Ihren Code schwer lesbar.




0

Ich denke, dass es von Ihrer Projektkomplexität abhängt, da Angular ziemlich modularisiert ist. Ihre Controller können zugeordnet werden und Sie können diese JavaScript-Klassen einfach in Ihre index.html-Seite importieren.

Aber falls Ihr Projekt größer wird. Oder wenn Sie ein solches Szenario vorwegnehmen, sollten Sie Winkel mit Anforderungen integrieren. In diesem Artikel sehen Sie eine Demo-App für eine solche Integration.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.