AmpersandJS / ampersand-view

A smart base view for Backbone apps, to make it easy to bind collections and properties to the DOM.
http://ampersandjs.com
MIT License
92 stars 39 forks source link

Notify parent view that child views have been rendered #70

Open luakri opened 10 years ago

luakri commented 10 years ago

With an ampersand view that has nested child views, it's child views are rendered with .renderCollection, everything works as expected.

How to notify the parent view that all its child views have completed rendering and appended the result to the DOM? eg the parent view when all its child views have been rendered, it needs to initialize a jQuery plugin that access elements from the child views?

luakri commented 10 years ago

Any thoughts on the above?

scottcorgan commented 10 years ago

Would love to see some events on collections as well. It's kind of a blackbox when you render collections.

luakri commented 10 years ago

Hello scottcorgan

Ampersand Collections have the same events as Backbone Collections eg add, remove, refresh, reset, sync, it is possible to create custom events. In my use case, I'm using ampersand-view-switcher and in my parent view i am listening for collection reset event, but there are scenarios where the collection event is not in sync with the view, the event is fired earlier than the view ready in the DOM.

For now i decided to integrate a npm module, that observes the DOM selector and notifies for changes, eg: selector-observer.

wraithgar commented 9 years ago

Can you monitor the 'rendered' property on the view? I believe it is intended for just such behavior.

scottcorgan commented 9 years ago

My thoughts on how it should work would be like a collection:

var things = this.renderCollection(someColleciton, SomeView, someElement);

things.views.on('add remove', function (view) {

});

My main reason for this feature would be expanding a parent container when a child is added or removed. I've hacked around this by listening to the collection itself and sizing all the children to resize the parent, but this introduces performance degradation when Having to do a lot adding and remove of children.

luakri commented 9 years ago

Hello @wraithgar, in your proposal to listen for the 'rendered' property how should i watch the attribute change?

wraithgar commented 9 years ago

The quickest way is once the view is instantiated, and before you render to do something like this.listenTo(view, 'change:rendered', someFunction);

luakri commented 9 years ago

Hello @wraithgar, i have tested the above code, placing it on the view/child view and also different approaches based on it.

The event does get fired, but the issue persists, when event is fired in a parent view the DOM of the child views is still not available.

Eg: parent view is a container 'DIV' which contains a list, and each 'LI' is a child view, event 'change:rendered' is triggered in the parent view but child view is not yet rendered in the DOM. If i listen for 'change:rendered' in the child view, the event will be triggered multiple times equal to the length of child views.

Any thoughts would be greatly appreciated, since neither with 'change:rendered' or listening for collection events, the parent view gets notified all the child views have finished rendering.

wraithgar commented 9 years ago

Yes you're right because you're doing this from a collection the solution isn't going to be that simple. The solution to this is going to be as @scottcorgan suggested, having collections be state objects that can have true prop attributes

luakri commented 9 years ago

It would be great to have such a feature as @scottcorgan mentioned above in ampersand, without the need to include third party npm modules or code.

cdaringe commented 9 years ago

this affects &-view, but at the end-of-the-day, the solution is really begging for extra work on &-collection-view to host an eventing Collection. I don't however, see the potential perf gains? @scottcorgan, how were you expecting better perf from your suggested solution?