You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
After playing around with the subviews property of ampersand-view I feel like it’s making it harder to work with a given subview than it has to be.
If I want to listen to an event from a subview for instance, it is not really clear where I would have to put my listenTo code, because the subview is initialized after some change event from the parent view.
My ideal scenario would look like this:
varAmpersandView=require("ampersand-view");varCollectionView=require("ampersand-collection-view");varViewSwitcher=require("ampersand-view-switcher");module.exports=AmpersandView.extend({template: "<div><div></div><ul data-hook=\"collection-container\"></ul></div>",subviews: {stuffView: {container: "[data-hook=collection-container]",constructor: CollectionView},tabSwitcher: {container: "[data-hook=switcher]",constructor: ViewSwitcher}},initialize: function(){AmpersandView.prototype.initialize.apply(this,arguments);// Because subviews are initialized with the view it’s save to// rely on them everywhere in the containing view.this.listenTo(this.stuffView,"some:event",this._handleSomeEvent);this.listenTo(this.tabSwitcher,"show",this._handleTabShow);// Alter subview properties or call subview methods without checking// if the subview is already initialized and having to handle it async.this.stuffView.collection=this.model.stuffCollection;},rerender: function(){// Maybe establish a `rerender` which only renders all the subviews but// leaves this views dom setup untouched ...this._renderSubviews();returnthis;},_handleSomeEvent: function(target,value){// handle `some:event` in here},_handleTabShow: function(target,value){// handle the `show` event in here}});
So basically I’m proposing to align the subview’s life-cycle with that of the parent view:
initialize calls _initializeSubviews() which initializes the configured subviews, registerSubview() them and assignes them to a property on this view.
render calls _renderSubviews() which calls renderSubview() for all initialized subviews. This could also be used for rerendering subviews.
remove calls remove() on all registered subviews.
Now if you want to do some work on a view before or after subviews are rendered you can override render and call View.prototype.render from there (In some cases this could address the need for events demanded in #70).
I think all of this could be implemented in a backwards compatible manner. So if this doesn’t suit your need you could call registerSubview() or renderSubview() like before.
One possible use case would be mitigating problems with binding server rendered views. Currently, if you want to attach a view instance to an existing element, subviews are a nightmare because they immediately render after a view is initialized.
It would be cool if we could establish a bind() method or something:
// bindable-view.jsvarAmpersandView=require("ampersand-view");module.exports=AmpersandView.extend({bind: function(el){// Attach view to given el and bind configured subviewsthis.el=el;this._bindSubviews();returnthis;},bindSubview: function(view,el){// Query this view for el selectorel=(typeofel==="string") ? this.query(el) : el;// Bind subview to found elview.bind(el);returnview;},_bindSubviews: function(){if(!this.subviews){return;}each(this.subviews,function(config,name){varsubview=this[name];this.bindSubview(subview,config.selector);},this);}});
And then we could use it to take over an existing DOM element:
<html><body><divid="my-view"><h1data-hook="title"></h1><p>This is some static text</p></div></body></html>
varBindableView=require("./bindable-view");varPageView=BindableView.extend({bindings: {"model.title": {type: "text",hook: "title"}}});varmyModel=newModel({title: "Hello"});varmyView=newPageView({model: myModel});// Attach myView to `#my-view` DOM elementmyView.bind(document.querySelector("#my-view"));// Altering the model now triggers DOM change as if this view was rendered// through javascript.myModel.title="Hi";// Rendering the whole thing would also work as expectedmyView.render();
So to sum things up: I think aligning the life-cycle phase of subviews with their parent views will give us a lot of flexibility.
So what’s everybody’s thought on this?
The text was updated successfully, but these errors were encountered:
After playing around with the
subviews
property ofampersand-view
I feel like it’s making it harder to work with a givensubview
than it has to be.If I want to listen to an event from a subview for instance, it is not really clear where I would have to put my
listenTo
code, because the subview is initialized after somechange
event from the parent view.My ideal scenario would look like this:
So basically I’m proposing to align the subview’s life-cycle with that of the parent view:
_initializeSubviews()
which initializes the configured subviews,registerSubview()
them and assignes them to a property on this view._renderSubviews()
which callsrenderSubview()
for all initialized subviews. This could also be used for rerendering subviews.remove()
on all registered subviews.Now if you want to do some work on a view before or after subviews are rendered you can override
render
and callView.prototype.render
from there (In some cases this could address the need for events demanded in #70).I think all of this could be implemented in a backwards compatible manner. So if this doesn’t suit your need you could call
registerSubview()
orrenderSubview()
like before.One possible use case would be mitigating problems with binding server rendered views. Currently, if you want to attach a view instance to an existing element,
subviews
are a nightmare because they immediately render after a view is initialized.It would be cool if we could establish a
bind()
method or something:And then we could use it to take over an existing DOM element:
So to sum things up: I think aligning the life-cycle phase of subviews with their parent views will give us a lot of flexibility.
So what’s everybody’s thought on this?
The text was updated successfully, but these errors were encountered: