Open codepunkt opened 10 years ago
I have the problem too. Every render
populates the container with a new version of the html.
In Chaplin.View
, why do you need to do this when the noWrap option is set:
# Undelegate the container events that were setup.
@undelegateEvents()
# Delegate events to the top-level container in the template.
@setElement el.firstChild, true
Shouldn't the element stay the same?
The current implementation wraps html returned by the templating function in a div
then pulls it out. I believe the correct approach for View#render
would be to use the template
element and look something like this:
if @noWrap
template = document.createElement 'template'
template.innerHTML = html
fragment = template.content
if fragment.children.length > 1
throw new Error 'There must be a single top-level element when ' +
'using `noWrap`.'
# Undelegate the container events that were setup.
@undelegateEvents()
# Delegate events to the top-level container in the template.
@setElement fragment, true
else
setHTML (if $ then @$el else @el), html
Notice how the above avoids the whole wrapping concept altogether. I believe that's the key.
However, the template
element, despite being a WC3 Established Standard and WebPlatform initiative, is not supported by IE11 or below though official support of the template
element is under consideration for a future version of IE.
Another approach would be to use of the kind of lame document.createDocumentFragment
method to construct DOM nodes programmatically, but that approach would be flimsy and prone to error IMO.
I would love to see a fix for this. Currently, we have the following workaround using jQuery's replaceWith
function:
class BaseView extends Chaplin.View
# noWrap bugfix for re-rendering
render: ->
elBefore = @$el
super
if @noWrap && elBefore? && !elBefore.is(document.body) && !elBefore.is(@$el)
elBefore.replaceWith @$el
This only works in projects with jQuery. CollectionView
needs to be extended the same way. Code might have some issues.
I'd expect the view in the DOM to be updated with the new information from the model - e.g. the same way this works in the TodoMVC Chaplin-App.
Due to this view being configured with
noWrap: true
, a call to render only changes the@el
and@$el
properties of the view instance, but neither removes the old@el
from the DOM nor inserts/appends the new one.Im trying to figure out how this should properly be done. How can i simply rerender a noWrap view on changes?