Closed shayne closed 8 years ago
I kind of think that it's a feature to have all of the templates included at the bottom of the asset package. Shouldn't your JavaScript that needs the templates to be loaded be waiting for DOMReady, and not executing the templates immediately?
I understand your point and maybe you can weigh in on my reasoning.
I'm building a simple example app using Rails, Backbone and Jammit. My backbone collections, models and views are loaded into memory before the DOM is ready, this seems logical to me.
The order specified is my assets.yml looks something like:
The common.js
files contains the Backbone models, views and collections.
Here's one of those views:
var TaskView = Backbone.View.extend({
tagName: "li",
events: {
"click .destroy" : "destroyTask"
},
template: JST["task"], // needs to have template in memory
initialize : function() {
this.render();
this.model.bind("change", _.bind(this.render, this));
},
render : function() {
$(this.el).html(this.template(this.model.toJSON()));
this.handleEvents();
return this;
},
destroyTask : function() {
this.model.destroy();
$(this.el).slideUp(300, function() {
$(this).remove();
});
return false;
}
});
With the Jammit always putting JSTs at the bottom I'd need to create three expansions in my assets.yml
:
This is a workaround really that adds two additional requests for JS just to accomodate an order of operations.
Interested at your take...
That's an excellent use case for doing ordered JavaScript template includes. I'll take a pass at merging your patch. For the time being, you can just look up the template from the JST object inside of the render
function...
I would use @Array.split@ or @Array.chunk@ to split array and preserve ordering even if there would be multiple template blocks. But sadly first is dependent on active_support/core_extensions and second on Ruby 1.9.2.
You could also not refer to global objects before they are defined and access them at "run time" (i.e. when the function is called):
var TaskView = Backbone.View.extend({
tagName: "li",
events: {
"click .destroy" : "destroyTask"
},
template: "task",
initialize : function() {
this.render();
this.model.bind("change", _.bind(this.render, this));
},
render : function() {
$(this.el).html(JST[this.template](this.model.toJSON()));
this.handleEvents();
return this;
},
destroyTask : function() {
this.model.destroy();
$(this.el).slideUp(300, function() {
$(this).remove();
});
return false;
}
});
+1 to this. In the meantime, lazy-evaluation of templates in the render function bypasses the issue.
I need this too...
+1 to this as well.
We're facing the same problem. It would also be the path of least confusion to make reasonable attempts to preserve the order.
any update on this pull request? it has only been opened for 10 months. :)
Nope -- just been busy, sorry about that.
+1 This would be nice to have.
I was surprised to learn that JST are included at the end... I'm curious about the rationale behind doing it that way verus just honoring the order specified in the assets.yml file.
Just came across this issue. +1 on keeping the include order.
+1
This patch is still valid, but PATH_TO_URL needs to be replaced with path_to_url. Thanks
+1. Hit a scenario where the document ready state is ALREADY true when the JS is being loaded in. This causes the application to start running as soon as it is loaded in before it has a chance to load in the templates (this is an IE8-only issue and is highly annoying). Using document on ready does not help in this scenario.
I'm surprised by this behaviour too, I workarounded it using the lazy-evaluation but still do not make sense.
+1 for merging, respecting the assets.yml order is a must :+1:
Ran into an issue where I needed some vendored libraries (like underscore and jQuery) loaded before my templates, but my application specific js (e.g. common.js, core.js) loaded after the templates.
Updates to packager and compressor.