Skip to content
This repository has been archived by the owner on Jun 15, 2023. It is now read-only.

Rerender of noWrap view doesn't work the way expected #731

Open
codepunkt opened this issue Dec 10, 2013 · 3 comments
Open

Rerender of noWrap view doesn't work the way expected #731

codepunkt opened this issue Dec 10, 2013 · 3 comments
Labels

Comments

@codepunkt
Copy link

class SomeView extends View
  noWrap: true
  template: template
  listen:
    'change model': 'render'

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?

@karellm
Copy link
Contributor

karellm commented Feb 9, 2014

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?

@ghost
Copy link

ghost commented Oct 7, 2014

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.

@sheinzle
Copy link

sheinzle commented May 3, 2015

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.

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

No branches or pull requests

3 participants