Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <blockquote> <ul> <li>How would binding work for objects?</li> <li>How listening to change in the form might work?</li> </ul> </blockquote> <h2>An abstraction that updates both objects</h2> <p>I suppose there are other techniques, but ultimately I'd have an object that holds reference to a related DOM element, and provides an interface that coordinates updates to its own data and its related element.</p> <p>The <code>.addEventListener()</code> provides a very nice interface for this. You can give it an object that implements the <code>eventListener</code> interface, and it'll invoke its handlers with that object as the <code>this</code> value.</p> <p>This gives you automatic access to both the element and its related data.</p> <h2>Defining your object</h2> <p>Prototypal inheritance is a nice way to implement this, though not required of course. First you'd create a constructor that receives your element and some initial data.</p> <pre><code>function MyCtor(element, data) { this.data = data; this.element = element; element.value = data; element.addEventListener("change", this, false); } </code></pre> <p>So here the constructor stores the element and data on properties of the new object. It also binds a <code>change</code> event to the given <code>element</code>. The interesting thing is that it passes the new object instead of a function as the second argument. <em>But this alone won't work.</em> </p> <h2>Implementing the <code>eventListener</code> interface</h2> <p>To make this work, your object needs to implement the <code>eventListener</code> interface. All that's needed to accomplish this is to give the object a <code>handleEvent()</code> method. </p> <p>That's where the inheritance comes in.</p> <pre><code>MyCtor.prototype.handleEvent = function(event) { switch (event.type) { case "change": this.change(this.element.value); } }; MyCtor.prototype.change = function(value) { this.data = value; this.element.value = value; }; </code></pre> <p>There are many different ways in which this could be structured, but for your example of coordinating updates, I decided to make the <code>change()</code> method only accept a value, and have the <code>handleEvent</code> pass that value instead of the event object. This way the <code>change()</code> can be invoked without an event as well.</p> <p>So now, when the <code>change</code> event happens, it'll update both the element and the <code>.data</code> property. And the same will happen when you call <code>.change()</code> in your JavaScript program.</p> <h2>Using the code</h2> <p>Now you'd just create the new object, and let it perform updates. Updates in JS code will appear on the input, and change events on the input will be visible to the JS code.</p> <pre><code>var obj = new MyCtor(document.getElementById("foo"), "20"); // simulate some JS based changes. var i = 0; setInterval(function() { obj.change(parseInt(obj.element.value) + ++i); }, 3000); </code></pre> <p><strong><em>DEMO:</em></strong> <a href="http://jsfiddle.net/RkTMD/">http://jsfiddle.net/RkTMD/</a></p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload