web-dev-qa-db-fra.com

Guidon, chargement de fichiers modèles externes

Mon objectif est de mettre tous mes modèles de guidons dans un seul dossier, comme suit:

templates/products.hbs
templates/comments.hbs

J'ai trouvé cet extrait à quelques endroits via une recherche rapide sur Google, qui apparemment se chargera dans les modèles de guidon dans des fichiers externes, ce qui est beaucoup plus logique que de mettre un tas de modèles dans un seul fichier d'index.

(function getTemplateAjax(path) {
    var source;
    var template;

    $.ajax({
        url: path, //ex. js/templates/mytemplate.handlebars
        cache: true,
        success: function(data) {
            source    = data;
            template  = Handlebars.compile(source);
            $('#target').html(template);
        }               
    });         
})()

Le problème est que je ne comprends pas cette fonction ni comment l'utiliser. Pourquoi la fonction entière est-elle entourée de parenthèses et ensuite appelée? par exemple. (function x() { ... })() Je ne sais pas ce que cela fait.

Et si je ne me trompe pas, on dirait que $('#target') est codé en dur alors qu'il ne devrait pas l'être. De plus, n'est-ce pas censé définir une variable data quelque part pour que les variables référencées dans le modèle fonctionnent? Il semble que la fonction correcte devrait être:

function getTemplateAjax(path, target, jsonData) {
  var source;
  var template;

  $.ajax({
    url: path, //ex. js/templates/mytemplate.handlebars
    cache: true,
    success: function(data) {
      source    = data;
      template  = Handlebars.compile(source);
      $(target).html(template(jsonData));
    }               
  });         
}

Remarque: si quelqu'un pouvait me diriger vers un meilleur moteur de modèle, qui prend en charge nativement les fichiers de modèle externes et est mieux organisé que les guidons, je serais éternellement reconnaissant.

Autre problème: je ne peux pas réellement nommer mes fichiers mytemplate.hbs, Car lorsque l'appel Ajax se produit, il le voit comme un fichier binaire et il apparaît comme binaire. Je suppose que c'est un problème de définition du type mime du serveur pour .hbs sur text/html ou text/plain, mais le problème est qu'il s'agit d'un serveur Grunt et je ne sais pas comment changer ses types mime.

27
CaptSaltyJack

Le code est enveloppé dans un IIFE ( Expression de fonction immédiatement invoquée), ce qui signifie que la fonction est exécutée immédiatement. Voilà ce que cela signifie:

(function x() {
  console.log('hello');
})();

Vous pouvez également faire:

(function() {
  console.log('hello');
}());

Les IIFE sont couramment utilisés pour créer une portée "privée" pour un peu de code afin qu'il joue Nice (n'entre pas en conflit) avec quoi que ce soit d'autre.


La deuxième fonction que vous avez fournie est plus logique et peut-être que la première ne doit être qu'un exemple.


Le guidon vous permet de précompiler vos modèles afin que vous n'ayez pas à les compiler au moment de l'exécution. De cette façon, vous n'avez pas à faire de requêtes HTTP supplémentaires juste pour charger le (s) modèle (s).

Par exemple, si j'ai la structure de projet suivante notez que mes modèles, collections et vues sont tous dans main.js juste pour cet exemple et tous mes .js les fichiers sont dans mon répertoire racine):

├── Gruntfile.js
├── handlebars-v2.0.0.js
├── index.html
├── main.js
├── package.json
└── templates
    └── todo.handlebars


Ma todo.handlebars ressemble à ça - juste du html avec la syntaxe du guidon:

<h3>{{title}}</h3>
<p>Created by: {{author}}</p>


Pour précompiler mon modèle, je procéderais comme suit dans la ligne de commande ( vous devez d'abord installer le script de précompilation du guidon avec: npm install -g handlebars):

> handlebars templates/todo.handlebars -f todo.tpl.js

Maintenant, la structure de mon projet ressemble à ceci:

├── Gruntfile.js
├── handlebars-v2.0.0.js
├── index.html
├── main.js
├── package.json
├── templates
│   └── todo.handlebars
└── todo.tpl.js

Vous verrez qu'un todo.tpl.js le fichier a été ajouté à mon répertoire racine. J'aurais pu l'appeler quelque chose de différent si je le voulais tant que l'extension est un .js car le fichier contient du code JavaScript valide. J'aurais également pu spécifier un répertoire différent pour le produire. N'oubliez pas que le todo.tpl.js fichier est le modèle réel que votre vue de réseau principal utilisera. Vous écrivez votre code HTML dans todo.handlebars et compilez-le comme todo.tpl.js.


Maintenant que j'ai le todo.tpl.js fichier Je peux utiliser Grunt pour peut-être concaténer tous mes fichiers de modèle JS dans un all_templates.js fichier ou je peux référencer chaque fichier directement dans mon HTML comme ceci:

  <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
  <script src="http://documentcloud.github.io/underscore/underscore-min.js"></script>
  <script src="http://documentcloud.github.io/backbone/backbone-min.js"></script>
  <script src="handlebars-v2.0.0.js"></script>
  <script src="todo.tpl.js"></script> <!-- My Template for a Todo item -->
  <script src="main.js"></script>


Dans ma vue Backbone, qui dans mon cas vit à l'intérieur de mon fichier main.js, j'obtenais le modèle comme ceci:

var TodoView = Backbone.View.extend({
  tagName: 'li',  
  className: 'todo-item',
  events: {

  },

  // You can grab your template function with the name you chose when
  // you precompiled it from: `Handlebars.templates`
  template: Handlebars.templates.todo,

  initialize: function(options) {
    this.listenTo(this.model, 'change', this.render);
  },

  render: function() {
    this.$el.html(this.template( this.model.toJSON() ));
    return this;
  }
});


Et tu as fini! Plus d'infos ici:

50
istos

Vous pouvez lire le modèle à partir d'un fichier externe, pas besoin de mettre du HTML avec une balise de script

$.get('templates/products.hbs', function (data) {
    var template=Handlebars.compile(data);
    $(target).html(template(jsonData));
}, 'html')
26
rinkesh

J'ai créé un plugin simple pour y parvenir. Plus d'informations à ce sujet: https://github.com/miketimmerman/load-template

1
Mike Timmerman