Skip to content
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

Allow application with pre-generated html #3128

Closed
dwt opened this issue Aug 16, 2016 · 27 comments
Closed

Allow application with pre-generated html #3128

dwt opened this issue Aug 16, 2016 · 27 comments
Assignees
Milestone

Comments

@dwt
Copy link

dwt commented Aug 16, 2016

Allow application with pre-generated html

  1. We want to create an application where the initial view html is pre-generated on the server
  2. This is relatively easy to achieve with Mn.View as it allows {template: false} to prevent it from trying to render anything
  3. However, there seems to be no equivalent of this for regions. That is, it's not possible to call app.showView(someView, {dontTouchTheFrickingHTML: true})

Expected behavior

I want a way to tell the application (really the region) that it shouldn't empty the element it's about to attach a view to.

Actual behavior

It always empties it. Even with {preventDestroy: true} which seems to be the only relevant option that is available.

Environment

  1. Marionette version: 3.0a5
  2. Backbone version: 1.3.3
@scott-w
Copy link
Member

scott-w commented Aug 16, 2016

Just so I understand, the definition of someView has template: false on it?

@dwt
Copy link
Author

dwt commented Aug 16, 2016

Of course. It works fine if I instantiate it directly without the application and it's regions - but the application and it's region support is actually what I want. :)

@scott-w
Copy link
Member

scott-w commented Aug 16, 2016

That sounds reasonable. I wonder if the best behaviour is to have the value of template tell the region manager whether to empty the el or not.

@paulfalgout
Copy link
Member

I think the way to accomplish this is to attach the view to the DOM element. That will mark that view as "rendered" then when you "show" it in the region it won't attempt to re-render it.

@paulfalgout
Copy link
Member

oh actually I see the issue.. this is a recent bugfix.. it's not the view rendering.. it's the region empty on show.. ugh..
https://github.com/marionettejs/backbone.marionette/blob/next/src/region.js#L210
This is a fix for if there was dom inside a region but no view.. the new view was just appended to the existing dom..

so.. somehow the region needs to know that the view it is being handled is currently a child of its $el or something like that.. hmmm

@paulfalgout
Copy link
Member

Actually no it works as I described:
https://jsfiddle.net/gzyew8Lw/1/

While the region's el does get detached.. it gets reattached when the view is shown..

Is this what you're looking to accomplish?

@dwt
Copy link
Author

dwt commented Aug 17, 2016

Indeed, setting the el does allow showView to be called without the existing dom being deleted.

Is this something that should be documented? Or should it be possible to tell a region that it shouldn't empty the existing dom?

I know I wasn't finding this solution from my trial and error and reading the docs + code, so maybe some documentation would be the solution?

What do you think?

@paulfalgout
Copy link
Member

Yeah I think documentation is in order.. not emptying the region could start all kinds of issues.

@rafde
Copy link
Member

rafde commented Aug 17, 2016

This reads as if @dwt wants to treat the region as a collection view like.
I don't know why you can't place the HTML in the region somewhere else and allow the region to act like a placeholder inserting a View.

@paulfalgout
Copy link
Member

I didn't read that at all.. it seemed to me like there was already attached DOM in the region that he wanted to be part of a single view. setting the view to know about the attached DOM prior to showing it seems correct to me... now I believe you could just as easily do the same thing with a collectionView where the childViews were aware of the els they were responsible for...

@ahumphreys87
Copy link
Member

this is something i have touched upon when looking into an isomorphic plugin. Gets tricky mapping the view back to the data in order to do manipulation though - its possible though. We almost have a working prototype here: https://github.com/BedeGaming/orchestra/tree/iso, with a demo app here: https://github.com/BedeGaming/orchestra-wires

@paulfalgout
Copy link
Member

can you explain, "view back to the data in order to do manipulation though" further?

@ahumphreys87
Copy link
Member

So imagine the server renders a table. You then want to sort the rows via some client side actions. To use CollectionView sort you would need the childViews to attach to a model. Kinda doing things in reverse

@paulfalgout
Copy link
Member

Note the collectionView version of this requires #3135

@paulfalgout paulfalgout added this to the v3.x milestone Aug 23, 2016
@jumika
Copy link

jumika commented Aug 24, 2016

How do I combine the technique shown in the jsfiddle if I want the view to replace the region's element?

@paulfalgout
Copy link
Member

@jumika a.showView(new V(), { replaceElement: true });

@oniric85
Copy link

Hi, I'm quite new to Marionette and I'm struggling applying this concept to a pre-generated HTML and a little of view composition. I'm trying to create an Application with a region which contains a View with two regions, let's call them header and main.

Here is a fiddle where I'm trying to demonstrate the concept but it's failing on missing DOM elements. Is such a scenario supported by Marionette?

@paulfalgout
Copy link
Member

@oniric85 fiddle?

@oniric85
Copy link

Oh sorry @paulfalgout! Here it is https://jsfiddle.net/oniric85/sy6xsb7u/

@paulfalgout
Copy link
Member

@oniric85 2 things. Since things are already rendered, you can put your showChildView in initialize and skip "re-rendering". But also if you update to https://cdnjs.cloudflare.com/ajax/libs/backbone.marionette/3.1.0/backbone.marionette.js instead of 3.0.0 your fiddle works

@oniric85
Copy link

@paulfalgout You mean I should avoid calling app.getView().render() ? I've also tried to simply swap Marionette version in the fiddle but it does not seems to get rid of the error on its own.

@paulfalgout
Copy link
Member

paulfalgout commented Oct 26, 2016

Ah yeah.. sorry.. avoid calling render.. what's happening is when you render the view (since it is actually re-rendering), the first thing it does is clean up and empty the regions, so it's actually removing the DOM from inside the regions of the view.. so once you get to onRender you're toast.

In fact I wouldn't use template: false at all. If you never plan on rendering a template and are always attaching DOM, then just use initialize to setup stuff. If you want to later allow the frontend to re-render the DOM, give it a template, but only render it when it needs to be re-rendered.

I think there's very little use-case for template:false. It's handy for jsfiddles when I'm looking at some functionality off of the lifecycle, but I don't care about the render.. otherwise I don't think it has a lot of value in v3.

@oniric85
Copy link

Thanks @paulfalgout, it's starting to make sense now :)

@paulfalgout
Copy link
Member

So to resolve this I think there's this behavioral issue:
#3227

And then we need to better document how this works in general. I suspect it needs to be it's own md file in addition to the bit we have in view lifecycle docs.

I still fall on the side of making the path to this clearer programmatically, but aside from not doing #3243 we should document this clearly. @marionettejs/marionette-core ? Anyone want to take this on?

@rafde
Copy link
Member

rafde commented Nov 13, 2016

https://jsfiddle.net/0wp0k7vs/6/
just pasting another example of it happening and a hacky solution for it.

@paulfalgout
Copy link
Member

@rafde I think template: false is the worst. I personally don't think anyone should use it and if there's no template to render onRender and calling render on the view should never happen:
https://jsfiddle.net/0wp0k7vs/7/

Now if you have a template to re-render the server rendered DOM it becomes a tad bit more complicated as you'll have to create children and other view stuff in both the initialize and the onRender But again I don't think template: false should apply here

@paulfalgout
Copy link
Member

closing as part of current work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants