Existe-t-il un moyen de faire en sorte qu'AngularJS charge des partiels au début et non au besoin?

190

J'ai une configuration d'itinéraire comme celle-ci:

var myApp = angular.module('myApp', []).
    config(['$routeProvider', function ($routeProvider) {
    $routeProvider.
        when('/landing', {
            templateUrl: '/landing-partial',
            controller: landingController
        }).
        when('/:wkspId/query', {
            templateUrl: '/query-partial',
            controller: queryController
        }).
        otherwise({
            redirectTo: '/landing'
        });
}]);

Je veux pouvoir faire en sorte que angularjs télécharge à la fois les partiels au début et non sur demande.

C'est possible?

Ranjith Ramachandra
la source

Réponses:

270

Oui, il existe au moins 2 solutions pour cela:

  1. Utilisez la scriptdirective ( http://docs.angularjs.org/api/ng.directive:script ) pour placer vos partiels dans le HTML initialement chargé
  2. Vous pouvez également remplir $templateCache( http://docs.angularjs.org/api/ng.$templateCache ) à partir de JavaScript si nécessaire (éventuellement en fonction du résultat de l' $httpappel)

Si vous souhaitez utiliser la méthode (2) pour remplir, $templateCachevous pouvez le faire comme ceci:

$templateCache.put('second.html', '<b>Second</b> template');

Bien sûr, le contenu des modèles peut provenir d'un $httpappel:

$http.get('third.html', {cache:$templateCache});

Voici le plunker ces techniques: http://plnkr.co/edit/J6Y2dc?p=preview

pkozlowski.opensource
la source
2
Merci pour la réponse. J'aime l'idée de cache de modèle car je ne veux pas mettre des choses dans une balise de script. Comment l'utiliser? La documentation est mauvaise. J'ai vu le violon dans l'un des commentaires. Mais je veux charger à partir d'une URL.
Ranjith Ramachandra
Mise à jour de la réponse en fonction des commentaires
pkozlowski.opensource
4
J'utilise parfois la <script>balise en ligne avec des inclusions côté serveur. Cela me permet de conserver mes partiels en tant que fichiers séparés à des fins d'organisation, tout en fournissant tout dans un seul document.
Blazemonger
2
Savez-vous s'il y a un gain de vitesse dans le choix d'une solution par rapport à une autre?
Atav32
2
Je mets en cache des modèles en utilisant un appel http, mais le problème est que le nom du modèle mis en cache serait l'URL par exemple: $ http.get ('app / correction / templates / group-correction-table.html', {cache: $ templateCache}); et chaque fois que je veux charger le modèle, je dois utiliser ce nom laid: (que je n'aime pas, comme ceci: <td ng-include = "'app / correction / templates / group-correction-table.html' ">
Shilan
25

Si vous utilisez Grunt pour construire votre projet, il existe un plugin qui assemblera automatiquement vos partiels dans un module Angular qui amorce $ templateCache. Vous pouvez concaténer ce module avec le reste de votre code et tout charger à partir d'un fichier au démarrage.

https://npmjs.org/package/grunt-html2js

Karlgold
la source
11
Il y a aussi grunt-angular-templatesqui fait le même genre de chose - npmjs.org/package/grunt-angular-templates - fonctionne un régal
Ben Walding
Cela fonctionne-t-il également pour les modèles du fichier d'index? J'ai un ng-view et un ng-include dans mon fichier d'index et j'ai du mal à faire apparaître mon application.
Batman
16

Ajoutez une tâche de construction pour concaténer et enregistrer vos partiels html dans Angular $templateCache. ( Cette réponse est une variante plus détaillée de la réponse de Karlgold. )

Pour grunt , utilisez grunt-angular-templates . Pour gulp , utilisez gulp-angular-templatecache .

Vous trouverez ci-dessous des extraits de configuration / code à illustrer.

gruntfile.js Exemple:

ngtemplates: {
  app: {                
    src: ['app/partials/**.html', 'app/views/**.html'],
    dest: 'app/scripts/templates.js'
  },
  options: {
    module: 'myModule'
  }
}

gulpfile.js Exemple:

var templateCache = require('gulp-angular-templatecache');
var paths = ['app/partials/.html', 'app/views/.html'];

gulp.task('createTemplateCache', function () {
return gulp.src(paths)
    .pipe(templateCache('templates.js', { module: 'myModule', root:'app/views'}))
    .pipe(gulp.dest('app/scripts'));
    });

templates.js (ce fichier est généré automatiquement par la tâche de construction)

$templateCache.put('app/views/main.html', "<div class=\"main\">\r"...

index.html

<script src="app/scripts/templates.js"></script>
<div ng-include ng-controller="main as vm" src="'app/views/main.html'"></div>
James Lawruk
la source
2
Salut @james J'utilise ce plugin gulp. Tous les fichiers .html se chargent correctement, mais lorsque j'essaie de spécifier html dans le cadre d'un plugin de boîte de dialogue (j'utilise ng-material), il lance 404. ex - $ mdDialog.show ({controller: 'entityGridCtrl', templateUrl: 'user / partials / entityGrid.html '});
Anand
Avez-vous remplacé mes références d'application / vues par vos utilisateurs / partiels?
James Lawruk
Merci. Je ne change pas le chemin des partiels, j'ai posté ma question - stackoverflow.com/questions/29399453/...
Anand
11

Si vous enveloppez chaque modèle dans une balise de script, par exemple:

<script id="about.html" type="text/ng-template">
<div>
    <h3>About</h3>
    This is the About page
    Its cool!
</div>
</script>

Concaténez tous les modèles dans un seul gros fichier. Si vous utilisez Visual Studio 2013, téléchargez Web Essentials - il ajoute un menu contextuel pour créer un bundle HTML.

Ajoutez le code que ce gars a écrit pour changer le $templatecacheservice angulaire - ce n'est qu'un petit morceau de code et cela fonctionne: Vojta Jina's Gist

C'est le $http.getqui devrait être changé pour utiliser votre fichier de bundle:

allTplPromise = $http.get('templates/templateBundle.min.html').then(

Vos itinéraires templateUrldevraient ressembler à ceci:

        $routeProvider.when(
            "/about", {
                controller: "",
                templateUrl: "about.html"
            }
        );
Simon Dowdeswell
la source
0

J'utilise juste ecopour faire le travail pour moi. ecoest pris en charge par Sprockets par défaut. C'est un raccourci pour Embedded Coffeescript qui prend un fichier eco et le compile dans un fichier de modèle Javascript, et le fichier sera traité comme tous les autres fichiers js que vous avez dans votre dossier de ressources.

Tout ce que vous avez à faire est de créer un modèle avec l'extension .jst.eco et d'y écrire du code html, et les rails compileront et serviront automatiquement le fichier avec le pipeline d'actifs, et le moyen d'accéder au modèle est vraiment simple: JST['path/to/file']({var: value});path/to/fileest basé sur le chemin logique, donc si vous avez un fichier /assets/javascript/path/file.jst.eco, vous pouvez accéder au modèle àJST['path/file']()

Pour le faire fonctionner avec angularjs, vous pouvez le passer dans l'attribut template au lieu de templateDir, et il commencera à fonctionner comme par magie!

Vérification au crayon
la source
Je ne suis pas sûr que cela réponde à la question, et changer le langage de programmation est probablement exagéré.
xdhmoore
0

Vous pouvez passer $ state à votre contrôleur, puis lorsque la page se charge et appelle le getter dans le contrôleur, vous appelez $ state.go ('index') ou tout autre partiel que vous souhaitez charger. Terminé.

rj905
la source
-1

Une autre méthode consiste à utiliser le cache d'application de HTML5 pour télécharger tous les fichiers une fois et les conserver dans le cache du navigateur. Le lien ci-dessus contient beaucoup plus d'informations. Les informations suivantes proviennent de l'article:

Modifiez votre <html>balise pour inclure un manifestattribut:

<html manifest="http://www.example.com/example.mf">

Un fichier manifeste doit être servi avec le type mime text/cache-manifest.

Un manifeste simple ressemble à ceci:

CACHE MANIFEST
index.html
stylesheet.css
images/logo.png
scripts/main.js
http://cdn.example.com/scripts/main.js

Une fois qu'une application est hors ligne, elle reste mise en cache jusqu'à ce que l'un des événements suivants se produise:

  1. L'utilisateur efface le stockage des données de son navigateur pour votre site.
  2. Le fichier manifeste est modifié. Remarque: la mise à jour d'un fichier répertorié dans le manifeste ne signifie pas que le navigateur remettra en cache cette ressource. Le fichier manifeste lui-même doit être modifié.
Brent Washburne
la source
1
malheureusement, cette fonctionnalité est maintenant obsolète developer.mozilla.org/en-US/docs/Web/HTML/… donc juste un avertissement, utilisez cette approche à vos risques
Lazy Coder
Selon la norme HTML, "Cette fonctionnalité est en train d'être supprimée de la plate-forme Web. (Il s'agit d'un processus long qui prend de nombreuses années.)" Le remplacement suggéré, Service Workers, est toujours une "technologie expérimentale" depuis début 2016. Pour l'instant, j'utilise toujours le cache d'application car il fonctionne bien pour mes applications.
Brent Washburne le