-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prevent reInit regions on render #3427
Comments
This is nearly the same as #1263 |
Oh I also think this should likely be accomplished with a flag on the region much like replaceElement. |
I had an idea for a quick solution that could be shipped into 3.5 before going all breaking for 4.0 I though we could either add a public Because changing the actual Render logic and adding a Ready event in the view lifecycle might need a major version and I think we should be able to propose this feature without breaking. |
The flag should be in view not in region since the proposed change would affect all regions in a view. Since the behavior is linked to the renderer an option is to pass as an parameter to
or change the signature of renderer, instead a function an object with a
It should work but it should not match 1:1 render event. For non destructive render would fire only in the first render The only concern i have is that Marionette.View has already a lot of events. I would try to replace one of the events by the new one, or change the behavior of a existing |
I think a renderer wanting nondestructive regions is a single use case for nondestructive regions, but a renderer is not the only use case so it should be per region. Particularly since the current behavior is the opposite. |
Modifying only setRenderer however for this one use case works for me if possible and won't conflict with future nondestructive regions |
like @blikblum, the use case I first though about is when setting a renderer, so all the regions of the view would be concerned. It is really tight to how the view handle its render, not on the region. For this use case (but maybe there is another use case tight to region, and maybe it is another change) I prefer a flag on the View or as @blikblum suggested an option pass along the |
I don't understand the public flag. If you do not change the rendered it would seem that the flag would merely disable the view |
Yeah I might think to big and expose more things than we need to expose, but I though it could be useful for some people in order to deactivate the re-init of the regions. Maybe with some particular DOM api... I dunno |
yep I'd lean towards not exposing it until another use case is clear. I think this is actually more different than I expected originally from #1263 as really what's happening here is we're indicating that the renderer will keep the regions from being destructive because it will manage keeping the children attached, where as the other is suggesting marionette keep them nondestructive and deal with the children. As such, I would suspect that we would not want marionette handling the nondestructive regions for such a renderer either. |
I still think it's quite the same than #1263 when I read the 1st post from James. The idea is to update View.setRenderer kind of like this render: function render() {
if (this._isDestroyed) {
return this;
}
this.triggerMethod('before:render', this);
// If this is not the first render call, then we need to
// re-initialize the `el` for each region
- if (this._isRendered) {
+ if (this._isRendered && !this._preventRegionReInit) {
this._reInitRegions();
}
this._renderTemplate();
this.bindUIElements();
this._isRendered = true;
this.triggerMethod('render', this);
return this;
},
...
}, {
// Sets the renderer for the Marionette.View class
- setRenderer: function setRenderer(renderer) {
+ setRenderer: function setRenderer(renderer, options) {
+ if (options.destructive === false) {
+ this.prototype._preventRegionReInit = true;
+ }
this.prototype._renderHtml = renderer;
}, I agree it still make sense to re-init the regions for now at each render with the default renderer behavior, so the suggestion of using a flag like |
I would use |
maybe a // from constructor
this.on('before:render', () => {
const regions= this._regions;
if(!_.isEmpty(regions)) {
_.reduce(regions, (usedRegions, region, name) => {
const view = region.detachView();
if (view) {
usedRegions[name] = view;
}
return usedRegions;
}, {});
this.once('render', () => {
_.each(usedRegions, (view, name) => this.showChildView(name, view));
});
}
}); super rough draft and probably super naive implementation. It's also missing how dealing with For the cases where you only need to show child views once, maybe a |
@rafde I think this is beginning to address #1263 but this issue is slightly different. In this case a renderer is used that does dom diffing and the user would mark the DOM children in a way that the differ would understand not to modify or remove the node. So you can re-render the layout template and it would diff in the changes without modifying the children.. however in this case since regions are rebuilt, it breaks anyways. This is not really related to how marionette deals with children. In fact this interface will only be useful in combination with a 3rd party renderer and some 3rd party convention for keeping the children rendered in place. I think a Marionette solution for this, that works in all cases is a better feature, but I think even in the case where it exists, users of these types of renderers/conventions will want to disable it as well. |
@rafde here's a gist of a POC I made a while back related to that: https://jsfiddle.net/k60445rf/2/ It's worth noting, and I had forgotten, that in the world of non-destructive regions, the |
@rafde The use case is really when using diffing / patching capable renders, like morphdom or hyperhtml. I ended up making a View like this const HyperView = Arlequin.View.extend({
_reInitRegions() { }
});
HyperView.setRenderer(hyperHtmlRenderer);
export default HyperView; Which is pretty ugly you have to admit, and not to document, so we have to find a better way |
I support @JSteunou proposition regardless of the variable name |
Now Marionette has a way to set multiple Renderer logic, it should also add a way to prevent regions to be re-initialized, because some renderer allow morphing the view by preserving actual regions content.
Either
_reInitRegions
shoud become public, or a new flag should be added into View.what do you think @marionettejs/marionette-core ?
The text was updated successfully, but these errors were encountered: