App views base renders subviews like magic
This commit is contained in:
parent
7c5e3cb415
commit
f5609f2182
6 changed files with 117 additions and 21 deletions
|
|
@ -8,6 +8,9 @@
|
||||||
%script{:id => "feedback-template", :type => 'text/template'}
|
%script{:id => "feedback-template", :type => 'text/template'}
|
||||||
!= File.read("#{Rails.root}/app/views/templates/feedback.ujs")
|
!= File.read("#{Rails.root}/app/views/templates/feedback.ujs")
|
||||||
|
|
||||||
|
%script{:id => "static-text-template", :type => 'text/template'}
|
||||||
|
!= File.read("#{Rails.root}/app/views/templates/static_text.ujs")
|
||||||
|
|
||||||
%script{:id => "stream-element-template", :type => 'text/template'}
|
%script{:id => "stream-element-template", :type => 'text/template'}
|
||||||
!= File.read("#{Rails.root}/app/views/templates/stream_element.ujs")
|
!= File.read("#{Rails.root}/app/views/templates/stream_element.ujs")
|
||||||
|
|
||||||
|
|
|
||||||
1
app/views/templates/static_text.ujs
Normal file
1
app/views/templates/static_text.ujs
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<span class=text><%= text %></span>
|
||||||
35
public/javascripts/app/views.js
Normal file
35
public/javascripts/app/views.js
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
App.Views.Base = Backbone.View.extend({
|
||||||
|
presenter : function(){
|
||||||
|
return this.defaultPresenter()
|
||||||
|
},
|
||||||
|
|
||||||
|
defaultPresenter : function(){
|
||||||
|
var modelJson = this.model ? this.model.toJSON() : {}
|
||||||
|
return _.extend(modelJson, App.user());
|
||||||
|
},
|
||||||
|
|
||||||
|
render : function() {
|
||||||
|
return this.renderTemplate().renderSubviews()
|
||||||
|
},
|
||||||
|
|
||||||
|
renderTemplate : function(){
|
||||||
|
this.template = _.template($(this.template_name).html());
|
||||||
|
var presenter = _.isFunction(this.presenter) ? this.presenter() : this.presenter
|
||||||
|
$(this.el).html(this.template(presenter));
|
||||||
|
this.postRenderTemplate();
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
postRenderTemplate : $.noop, //hella callbax yo
|
||||||
|
|
||||||
|
renderSubviews : function(){
|
||||||
|
var self = this;
|
||||||
|
_.each(this.subviews, function(property, selector){
|
||||||
|
var view = _.isFunction(self[property]) ? self[property]() : self[property]
|
||||||
|
self.$(selector).html(view.render().el)
|
||||||
|
view.delegateEvents();
|
||||||
|
})
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
App.Views.StreamObject = Backbone.View.extend({
|
App.Views.StreamObject = App.Views.Base.extend({
|
||||||
|
|
||||||
className : "loaded",
|
className : "loaded",
|
||||||
|
|
||||||
initialize: function(options) {
|
initialize: function(options) {
|
||||||
|
|
@ -10,24 +9,5 @@ App.Views.StreamObject = Backbone.View.extend({
|
||||||
destroyModel: function(evt){
|
destroyModel: function(evt){
|
||||||
if(evt){ evt.preventDefault(); }
|
if(evt){ evt.preventDefault(); }
|
||||||
this.model.destroy();
|
this.model.destroy();
|
||||||
},
|
|
||||||
|
|
||||||
presenter : function(){
|
|
||||||
return this.defaultPresenter()
|
|
||||||
},
|
|
||||||
|
|
||||||
defaultPresenter : function(){
|
|
||||||
var modelJson = this.model ? this.model.toJSON() : {}
|
|
||||||
return _.extend(modelJson, App.user());
|
|
||||||
},
|
|
||||||
|
|
||||||
render : function() {
|
|
||||||
return this.renderTemplate()
|
|
||||||
},
|
|
||||||
|
|
||||||
renderTemplate : function(){
|
|
||||||
this.template = _.template($(this.template_name).html());
|
|
||||||
$(this.el).html(this.template(this.presenter()));
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
76
spec/javascripts/app/views_spec.js
Normal file
76
spec/javascripts/app/views_spec.js
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
describe("App.Views.Base", function(){
|
||||||
|
function stubView(text){
|
||||||
|
var stubClass = Backbone.View.extend({
|
||||||
|
render : function(){
|
||||||
|
$(this.el).html(text)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return new stubClass
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("#render", function(){
|
||||||
|
beforeEach(function(){
|
||||||
|
var staticTemplateClass = App.Views.Base.extend({ template_name : "#static-text-template" })
|
||||||
|
|
||||||
|
this.model = new Backbone.Model({text : "model attributes are in the default presenter"})
|
||||||
|
this.view = new staticTemplateClass({model: this.model})
|
||||||
|
this.view.render()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("renders the template with the presenter", function(){
|
||||||
|
expect($(this.view.el).text().trim()).toBe("model attributes are in the default presenter")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("it evaluates the presenter every render", function(){
|
||||||
|
this.model.set({text : "OMG It's a party" })
|
||||||
|
this.view.render()
|
||||||
|
expect($(this.view.el).text().trim()).toBe("OMG It's a party")
|
||||||
|
})
|
||||||
|
|
||||||
|
context("subViewRendering", function(){
|
||||||
|
beforeEach(function(){
|
||||||
|
var viewClass = App.Views.Base.extend({
|
||||||
|
template_name : "#static-text-template",
|
||||||
|
subviews : {
|
||||||
|
".subview1": "subview1",
|
||||||
|
".subview2": "createSubview2"
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize : function(){
|
||||||
|
this.subview1 = stubView("OMG First Subview")
|
||||||
|
},
|
||||||
|
|
||||||
|
presenter: {
|
||||||
|
text : "this comes through on the original render"
|
||||||
|
},
|
||||||
|
|
||||||
|
postRenderTemplate : function(){
|
||||||
|
$(this.el).append("<div class=subview1/>")
|
||||||
|
$(this.el).append("<div class=subview2/>")
|
||||||
|
console.log($(this.el).html())
|
||||||
|
},
|
||||||
|
|
||||||
|
createSubview2 : function(){
|
||||||
|
return stubView("furreal this is the Second Subview")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.view = new viewClass().render()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("repsects the respects the template rendered with the presenter", function(){
|
||||||
|
expect(this.view.$('.text').text().trim()).toBe("this comes through on the original render")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("renders subviews from views that are properties of the object", function(){
|
||||||
|
expect(this.view.$('.subview1').text().trim()).toBe("OMG First Subview")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("renders the sub views from functions", function(){
|
||||||
|
expect(this.view.$('.subview2').text().trim()).toBe("furreal this is the Second Subview")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
@ -38,6 +38,7 @@ src_files:
|
||||||
|
|
||||||
- public/javascripts/app/app.js
|
- public/javascripts/app/app.js
|
||||||
- public/javascripts/app/router.js
|
- public/javascripts/app/router.js
|
||||||
|
- public/javascripts/app/views.js
|
||||||
- public/javascripts/app/models/*
|
- public/javascripts/app/models/*
|
||||||
- public/javascripts/app/collections/*
|
- public/javascripts/app/collections/*
|
||||||
- public/javascripts/app/views/stream_object_view.js
|
- public/javascripts/app/views/stream_object_view.js
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue