可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Simply enough I do not want to define all my handlebar templates in my html file
I tried this
<script type="text/x-handlebars" data-template-name="nav-bar" src="template.handlebar"></script>
But this did not work. Can I not define templates my template programmatically or even just load handlebar files so that I can reuse and also I feel it makes things a bit more maintainable.
I tried just loading them with ajax and appending them to the head, this works fine I can see it there but ember.js doesn't read it after ember has already been loaded and the templates are not defined.
回答1:
Or define handlebar templates programatically in Ember.js
You can define templates programmatically by using Ember.Handlebars.compile
, see http://jsfiddle.net/pangratz666/wxrxT/:
Ember.View.create({
personName: 'Dr. Tobias Fünke',
template: Ember.Handlebars.compile('Hello {{personName}}')
}).append();
Or you add compiled templates to Ember.TEMPLATES
array, see http://jsfiddle.net/pangratz666/58tFP/:
Ember.TEMPLATES['myFunkyTemplate'] = Ember.Handlebars.compile('Hello {{personName}}');
Ember.View.create({
personName: 'Dr. Tobias Fünke',
templateName: 'myFunkyTemplate'
}).append();
I would recommend to use some tools like Richard Millan stated. Also take a look at interline/ember-skeleton which offers support for compilation of templates.
回答2:
You can also patch Ember View to load templates on 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;
}
});
UPDATE: Since Ember 1.0.0-pre.3 this solution probabaly no more work (maybe can be migrated to recent Ember)
回答3:
So since I still wanted separate files for my templates and I didn't want to define them in strings in the javascript I hacked this together last night
It is a synchronous lazy loader, it loads all the templates first, then ember and the rest of my 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: I cleaned it up and made it work properly only testing in chrome though
回答4:
It is possible, but you will need to precompile your templates first. This will also allow you to include all your templates within one file.
- If you are using Rails, you can use the ember-rails gem to do it for you.
- Otherwise you can follow these instructions on how to precompile handlebars
Later on, you will need to include the javascript file.
<script src="path/to/compiled/templates.js" type="text/javascript"></script>
回答5:
If you load your templates into the DOM before loading Ember, then you don't need to compile or register your templates. Ember will come along after and do it for you.
Here is an article showing how:
http://weboriented.wordpress.com/2012/09/02/loading-handlebars-templates-in-ember-using-curl-js/
回答6:
Here's another solution, inside your Ember view/component:
var viewClass = Ember.View.extend({ templateName: this.get('contentTemplate') });
var view = this.createChildView(viewClass);
var html = view.renderToBuffer().buffer;
回答7:
This is an old question, so all the answers are a bit outdated. With Ember CLI templates are auto loaded by naming convention as require.js modules. It's a bit odd, since you write proposed ES6 import syntax and the build transpiles it into require.js syntax, but it works really well.
回答8:
It is possible, and yes, you can do it without usage of another another another tool, just using ember.js and nothing else. i did it like this:
1) html code. note that all handlebars files need to be loaded before using any of them. here, its just one file named handlebars.js
<body>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/libs/jquery-1.7.2.min.js"><\/script>')</script>
<script src="js/libs/ember-0.9.8.1.min.js"></script>
<script src="js/handlebars.js"></script>
<script src="js/app.js"></script>
</body>
2) this file handlebars.js contains the following, using the compiler of ember
var src = "Hello, <b>{{name}}</b>";
Em.TEMPLATES["say-hello"] = Em.Handlebars.compile(src);
3) and then inside your app.js file, just use it as it were available (which it is):
var hu = Em.View.create({
templateName: "say-hello",
name: "Allô",
mouseDown: function() {
window.alert("hello world!");
}
});
hu.appendTo("body");