webentwicklung-frage-antwort-db.com.de

Relative templateUrl wird geladen

Ich habe versucht, den besten Weg zu finden, um eine modulare, skalierbare angular Anwendung zu erstellen. Ich mag die Struktur von Projekten wie eckige-Kesselplatte , angle-app , wobei alle zugehörigen Dateien nach Merkmalen für Teilstriche und Direktiven gruppiert werden.

project
|-- partial
|   |-- partial.js
|   |-- partial.html
|   |-- partial.css
|   |-- partial.spec.js

In all diesen Beispielen wird die Vorlagen-URL jedoch relativ zur Basis-URL und nicht relativ zur aktuellen Datei geladen:

angular.module('account', [])
.config(function($stateProvider) {
  $stateProvider.state('account', {
    url: '/account',
    templateUrl: 'main/account/account.tpl.html', // this is not very modular
    controller: 'AccountCtrl',
  });
})

Dies ist nicht sehr modular und kann bei großen Projekten schwierig zu warten sein. Ich muss daran denken, den templateUrl -Pfad jedes Mal zu ändern, wenn ich eines dieser Module verschiebe. Es wäre schön, wenn es eine Möglichkeit gäbe, die Vorlage relativ zur aktuellen Datei zu laden:

templateUrl: './account.tpl.html'

Gibt es eine Möglichkeit, so etwas im Winkel zu machen?

42
Danny Nelson

Ich denke, Sie werden irgendwann feststellen, dass es schwieriger sein wird, die Pfade relativ zur js-Datei zu pflegen, wenn es überhaupt möglich ist. Wenn es soweit ist, möchten Sie höchstwahrscheinlich alle Ihre Javascript-Dateien zu einer Datei verketten. In diesem Fall möchten Sie, dass die Vorlagen relativ zur baseUrl sind. Wenn Sie die Vorlagen über Ajax abrufen, was Angular standardmäßig der Fall ist, es sei denn, Sie packen sie im $ templateCache vor, möchten Sie sie auf jeden Fall relativ zur baseUrl, also dem Der Server weiß, wo sie zu finden sind, sobald Ihre js-Datei bereits an den Browser gesendet wurde.

Vielleicht liegt der Grund dafür, dass Sie sie nicht gerne in Bezug auf die baseUrl in der Entwicklung haben, darin, dass Sie keinen Server lokal betreiben? Wenn das der Fall ist, würde ich das ändern. Dies erleichtert Ihnen das Leben erheblich, insbesondere, wenn Sie mit Routen arbeiten. Ich würde auschecken Grunt , es hat einen sehr einfachen Server, den Sie lokal ausführen können, um ein Produktionssetup namens Grunt Connect nachzuahmen. Sie können auch ein Projekt wie Yeoman auschecken, das eine vorgefertigte Front-End-Entwicklungsumgebung mit Grunt bereitstellt, sodass Sie nicht viel Zeit für die Einrichtung aufwenden müssen. Das Angular Seed Projekt ist ein gutes Beispiel für ein Grunt-Setup für die lokale Entwicklung.

16
Charlie Martin

Der beste Weg, dies jetzt zu tun, ist die Verwendung eines Modulladers wie browserify, webpack oder TypeScript. Es gibt auch viele andere. Da die Anforderungen anhand des relativen Speicherorts der Datei erstellt werden können und der zusätzliche Vorteil des Importierens von Vorlagen über Transformationen oder Loader wie Partialify besteht, müssen Sie nicht einmal mehr Vorlagen-URLs verwenden. Einfach das Template über eine Anforderung einbinden.

Meine alte Antwort ist unten noch verfügbar:

Ich schrieb einen Beitrag zu genau diesem Thema und sprach auf unserem lokalen Angular Meetup darüber. Die meisten von uns verwenden es jetzt in der Produktion.

Dies ist recht einfach, solange Ihre Dateistruktur in Ihren Modulen effektiv dargestellt wird. Hier ist eine kurze Vorschau der Lösung. Vollständiger Artikel-Link folgt.

var module = angular.module('myApp.things', []);

var all = angular.module('myApp.things.all', [
    'myApp.things',
    'things.someThing',
    'things.someOtherThing',
    'things.someOtherOtherThing',
]);

module.paths = {
    root: '/path/to/this/thing/',
    partials: '/path/to/this/thing/partials/',
    sub: '/path/to/this/thing/sub/',
};

module.constant('THINGS_ROOT', module.paths.root);
module.constant('THINGS_PARTIALS', module.paths.partials);
module.constant('THINGS_SUB', module.paths.sub);

module.config(function(stateHelperProvider, THINGS_PARTIALS) {

    stateHelperProvider.setNestedState({
        name: 'things',
        url: '/things',
        templateUrl: THINGS_PARTIALS + 'things.html',
    });
});

Und dann sehen alle Submodule oder "relativen" Module so aus:

var module = angular.module('things.someThing', ['myApp.things']);
var parent = angular.module('myApp.things');

module.paths = {
    root: parent.paths.sub + '/someThing/',
    sub: parent.paths.sub + '/someThing/sub/',
    partials: parent.paths.sub + '/someThing/module/partials/',
};

module.constant('SOMETHING_ROOT', module.paths.root);
module.constant('SOMETHING_PARTIALS', module.paths.partials);
module.constant('SOMETHING_SUB', module.paths.sub);

module.config(function(stateHelperProvider, SOMETHING_PARTIALS) {

    stateHelperProvider.setNestedState({
        name: 'things.someThing',
        url: "/someThing",
        templateUrl: SOMETHING_PARTIALS + 'someThing.html',
    });
});

Hoffe das hilft!

Vollständiger Artikel: Relative AngularJS Modules

Prost!

15
tannerlinsley

Ich habe jetzt eine Weile auf diesem Thema gekaut. Ich benutze gulp, um meine Vorlagen für die Produktion zu packen, aber ich hatte Mühe, eine Lösung zu finden, mit der ich für die Entwicklung zufrieden war.

Hier bin ich gelandet. Mit dem folgenden Snippet können Sie eine beliebige URL nach Belieben neu verkabeln.

angular.module('rm').config(function($httpProvider) {

  //this map can be defined however you like
  //one option is to loop through script tags and create it automatically
  var templateMap = {
    "relative.tpl.html":"/full/path/to/relative.tpl.html",
    etc...
  };

  //register an http interceptor to transform your template urls
  $httpProvider.interceptors.Push(function () {
    return {
      'request': function (config) {
        var url = config.url;
        config.url = templateMap[url] || url;
        return config;
      }
    };
  });
});
1
Tom Makin

Derzeit ist es möglich, mit systemJs modules loader das zu tun, was Sie wollen.

import usersTemplate from './users.tpl';

var directive = {
   templateUrl: usersTemplate.name
}

Sie können hier ein gutes Beispiel überprüfen https://github.com/swimlane-contrib/angular1-systemjs-seed

1