web-dev-qa-db-fra.com

Est-il possible de charger un modèle de guidon avec une balise script? Ou définissez des modèles de guidon par programme dans Ember.js

Assez simplement, je ne veux pas définir tous mes modèles de guidon dans mon fichier html

J'ai essayé ça

<script type="text/x-handlebars" data-template-name="nav-bar" src="template.handlebar"></script>

Mais cela n'a pas fonctionné. Ne puis-je pas définir les modèles de mon modèle par programme ou même simplement charger des fichiers de guidon afin de pouvoir les réutiliser; je pense également que cela rend les choses un peu plus faciles à gérer.

J'ai juste essayé de les charger avec ajax et de les ajouter à la tête, cela fonctionne très bien. Je peux le voir ici, mais ember.js ne le lit pas après qu'ember ait déjà été chargé et les modèles ne sont pas définis.

21
timanema

Ou définissez des modèles de guidon par programmation dans Ember.js

Vous pouvez définir des modèles par programme en utilisant Ember.Handlebars.compile, voir http://jsfiddle.net/pangratz666/wxrxT/ :

Ember.View.create({
    personName: 'Dr. Tobias Fünke',
    template: Ember.Handlebars.compile('Hello {{personName}}')
}).append();​

Ou vous ajoutez des modèles compilés au tableau Ember.TEMPLATES, voir http://jsfiddle.net/pangratz666/58tFP/ :

Ember.TEMPLATES['myFunkyTemplate'] = Ember.Handlebars.compile('Hello {{personName}}');

Ember.View.create({
    personName: 'Dr. Tobias Fünke',
    templateName: 'myFunkyTemplate'
}).append();​

Je recommanderais d'utiliser des outils tels que Richard Millan déclaré. Jetez également un coup d'œil à interline/ember-skeleton , qui offre un support pour la compilation de modèles.

9
pangratz

Vous pouvez également patcher Ember View pour charger des modèles sur get

Em.View.reopen({
    templateForName: function(name, type) {
        if (!name) { return; }

        var templates = Em.get(this, 'templates'),
            template = Em.get(templates, name);

        if (!template) {
            $.ajax({
                url: 'templates/%@.hbs'.fmt(name),
                async: false
            }).success(function(data) {
                template = Ember.Handlebars.compile(data);
            });
        }

        if (!template) {
            throw new Em.Error('%@ - Unable to find %@ "%@".'.fmt(this, type, name));
        }

        return template;
    }
});

MISE À JOUR: Depuis Ember 1.0.0-pre.3, cette solution ne fonctionnait probablement plus (peut être migrée vers Ember récent)

9
farincz

Donc, comme je voulais toujours des fichiers séparés pour mes modèles et que je ne voulais pas les définir en chaînes dans le javascript, j'ai piraté cela ensemble hier soir

C'est un chargeur paresseux synchrone, il charge tous les modèles en premier, puis ember et le reste de mon code,

        //fake function so that every loads fine will get redefined in application.js
        function initializeApp(){}

        function loadTemplates(){
            var arg = arguments[0],
                next = Array.prototype.slice.call(arguments,1);
            if(typeof arg != 'string'){
                arg()
            }else{
                var scriptObj = document.createElement('script');
                scriptObj.type = 'text/x-handlebars';
                $(scriptObj).attr('data-template-name', arg.replace('.handlebars', '').substring(arg.lastIndexOf('/')+1))
                $.get(arg, function(data){
                    scriptObj.text = data;
                    document.head.appendChild(scriptObj);
                    if(next.length > 0) loadTemplates.apply(this, next);
                });
            }
        }

        function loadScripts() {
            var script = arguments[0],
                scriptObj = document.createElement('script'),
                next = Array.prototype.slice.call(arguments,1);
            scriptObj.type = 'text/javascript';
            scriptObj.src = script;
            scriptObj.onload = scriptObj.onreadystatechange = (next.length > 0) ? function(){loadScripts.apply(this, next)} : function(){$(document).ready(function() {initializeApp()})};
            document.head.appendChild(scriptObj);
        }

        function loadApp(obj){
            loadTemplates.apply(this, obj.templates.concat(function(){loadScripts.apply(this,obj.scripts)}))
        }

        window.onload = function(){
            loadApp({
                templates:
                    [
                        '/javascripts/views/templates/nav-bar.handlebars',
                    ],
                scripts:
                    [
                        'https://maps.googleapis.com/maps/api/js?sensor=false&callback=initializeGoogleMaps',
                        '/javascripts/lib/bootstrap.js', 
                        '/javascripts/lib/Rails.js', 
                        '/javascripts/lib/ember.js',
                        '/javascripts/application.js',
                        '/javascripts/views/nav_bar.js',
                    ]
            })
        }

EDIT: Je l'ai nettoyé et l'ai fait fonctionner correctement uniquement en chrome

5
timanema

Si vous chargez vos modèles dans le DOM avant de charger Ember, vous n'avez pas besoin de compiler ou d'enregistrer vos modèles. Ember viendra après et le fera pour vous.

Voici un article montrant comment:

http://weboriented.wordpress.com/2012/09/02/loading-handlebars-templates-in-ember-using-curl-js/

1
Chris Jensen

C'est possible, mais vous devrez d'abord précompiler vos modèles. Cela vous permettra également d'inclure tous vos modèles dans un seul fichier.

Plus tard, vous devrez inclure le fichier javascript.

<script src="path/to/compiled/templates.js" type="text/javascript"></script>
1
Richard Millan

Voici une autre solution, dans votre vue/composant Ember:

var viewClass = Ember.View.extend({ templateName: this.get('contentTemplate') });
var view = this.createChildView(viewClass);
var html = view.renderToBuffer().buffer;
0
briangonzalez

C'est une vieille question, alors toutes les réponses sont un peu dépassées. Avec Ember CLI les modèles sont chargés automatiquement par convention de nommage en tant que modules require.js. C'est un peu étrange, car vous écrivez la syntaxe d'importation ES6 proposée et que la construction la transforme en syntaxe require.js, mais cela fonctionne vraiment bien.

0
Robin Clowers