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

preserve-inputs conflicts with #constant #1301

Closed
awwx opened this Issue Aug 13, 2013 · 1 comment

Comments

Projects
None yet
2 participants
@awwx
Contributor

awwx commented Aug 13, 2013

This is an example of a constant region which is no longer constant when the preserve-inputs packages is used. It looks like if the constant region contains an input element with an id (one of the things that preserve-inputs tries to preserve), the constant region is no longer constant (it gets fixed up, instead of only being added or removed as a whole). preserve-inputs shouldn't affect constant regions.

(The unnamed collection N is used here instead of a simple Session variable to store the incrementing number because doing that triggers another variant of the bug, see below).

<body>
  {{> button}}
  {{> hello}}
</body>

<template name="button">
  <div><button>Inc</button></div>
</template>

<template name="hello">
  {{#with N}}
    <div>{{n}}</div>
    {{> stuff}}
  {{/with}}
</template>

<template name="stuff">
  {{#constant}}
    <div id="foo">
      <input id="bar" type="text">
    </div>
  {{/constant}}
</template>


return unless Meteor.isClient

@N = new Meteor.Collection(null)
N.insert {_id: 'singleton', n: 0}

Template.button.events
  'click button': ->
    N.update('singleton', {$inc: {n: 1}})

Template.hello.N = -> N.findOne('singleton')

Template.stuff.rendered = ->
  if $('.stuff', '#foo').length is 0
    console.log 'adding stuff', $('#bar').data('marked')
    $('#foo').append('<div class="stuff">stuff</div>')
    $('#bar').data('marked', true)
  return

Run this without preserve-inputs, and it works correctly: "adding stuff" is printed once at startup. Clicking the button increments the displayed number, but "adding stuff" isn't displayed again. (Without the constant region it would be because the template would get re-rendered, removing the added "stuff" div).

Now add preserve-inputs. This time the #constant region is no longer constant: click the button, and "adding stuff" is printed again.

This turns out to be especially bad with jQuery plugins that attach some data to an element as an indicator that the plugin has initialized. Because the data is still there attached to the input element, the plugin thinks that it has been initialized (which is was), but the plugin gets confused because the extra elements it added are missing.

In summary, a constant region should only be added or removed as a whole, it shouldn't be modified on re-render. preserve-inputs doesn't need to go into constant regions.

Fun variants (with preserve-inputs included), probably related to the same bug:

Move the button into the "hello" template. After clicking the button once, the button event handler is no longer called when the button is clicked again.

Rather than using "#with" and a unnamed collection, use a simple Session variable instead:

<template name="hello">
  <div>{{n}}</div>
  {{> stuff}}
</template>

Template.hello.n = -> Session.get('n')

and have the button increment n. Now

Exception from Deps afterFlush function: TypeError: Cannot read property 'lastChild' of null
    at findPosition (http://localhost:3000/packages/liverange.js?b3097d72d458e645fd4f0021c8ff5189abe8d98a:204:52)
    at new LiveRange (http://localhost:3000/packages/liverange.js?b3097d72d458e645fd4f0021c8ff5189abe8d98a:158:20)
    at notifyWatchers (http://localhost:3000/packages/spark.js?c9939ae1b11c764e0ce2709f852e72f6382467e6:145:19)
    at http://localhost:3000/packages/spark.js?c9939ae1b11c764e0ce2709f852e72f6382467e6:463:5
    at _.extend.flush (http://localhost:3000/packages/deps.js?5ac28feec1f3e0539889ecde598dd9d01e408b41:265:11) 
@glasser

This comment has been minimized.

Show comment
Hide comment
@glasser

glasser Apr 22, 2014

Member

We've totally rewritten Meteor's live HTML system with Blaze in 0.8.0; preserve-inputs and #constant no longer exist.

Member

glasser commented Apr 22, 2014

We've totally rewritten Meteor's live HTML system with Blaze in 0.8.0; preserve-inputs and #constant no longer exist.

@glasser glasser closed this Apr 22, 2014

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