sc_require(“handlebars”); sc_require(“ext/handlebars”); sc_require(“ext/handlebars/bind”); sc_require(“ext/handlebars/collection”); sc_require(“ext/handlebars/localization”); sc_require(“ext/handlebars/view”);
// Global hash of shared templates. This will automatically be populated // by the build tools so that you can store your Handlebars templates in // separate files that get loaded into JavaScript at buildtime. SC
.TEMPLATES = SC
.Object.create();
/** @class
SC.TemplateView allows you to create a view that uses the Handlebars templating engine to generate its HTML representation. To use it, create a file in your project called +mytemplate.handlebars+. Then, set the +templateName+ property of your SC.TemplateView to +mytemplate+. Alternatively, you can set the +template+ property to any function that returns a string. It is recommended that you use +SC.Handlebars.compile()+ to generate a function from a string containing Handlebars markup. @extends SC.CoreView @since SproutCore 1.5
*/ SC
.TemplateView = SC
.CoreView.extend( /** @scope SC
.TemplateView.prototype */ {
// This makes it easier to build custom views on top of TemplateView without // gotchas, but may have tab navigation repercussions. The tab navigation // system should be revisited. acceptsFirstResponder: YES, /** The name of the template to lookup if no template is provided. SC.TemplateView will look for a template with this name in the global +SC.TEMPLATES+ hash. Usually this hash will be populated for you automatically when you include +.handlebars+ files in your project. @type String */ templateName: null, /** The hash in which to look for +templateName+. Defaults to SC.TEMPLATES. @type Object */ templates: SC.TEMPLATES, /** The template used to render the view. This should be a function that accepts an optional context parameter and returns a string of HTML that will be inserted into the DOM relative to its parent view. In general, you should set the +templateName+ property instead of setting the template yourself. @type Function */ template: function(key, value) { if (value !== undefined) { return value; } var templateName = this.get('templateName'), template = this.get('templates').get(templateName); if (!template) { //@if(debug) if (templateName) { SC.Logger.warn('%@ - Unable to find template "%@".'.fmt(this, templateName)); } //@endif return function() { return ''; }; } return template; }.property('templateName').cacheable(), /** The object from which templates should access properties. This object will be passed to the template function each time the render method is called, but it is up to the individual function to decide what to do with it. By default, this will be the view itself. @type Object */ context: function(key, value) { if (value !== undefined) { return value; } return this; }.property().cacheable(), /** When the view is asked to render, we look for the appropriate template function and invoke it, then push its result onto the passed SC.RenderContext instance. @param {SC.RenderContext} context the render context */ render: function(context) { var data, output, template = this.get('template'), templateContext = this.get('context'); this._didRenderChildViews = YES; data = { view: this, isRenderData: true }; output = template(templateContext, { data: data }); context.push(output); }, // in TemplateView, updating is handled by observers created by helpers in the // template. As a result, we create an empty update method so that the old // (pre-1.5) behavior which would force a full re-render does not get activated. update: function() { }, /** Since mouseUp events will not fire unless we return YES to mouseDown, the default mouseDown implementation returns YES if a mouseDown method exists. */ mouseDown: function() { if (this.mouseUp) { return YES; } return NO; }
});