Hi,

This is a classic problem, which can probably be easily summed up like
this:

    var index;
    for (index = 0; index < 5; ++index) {
        $('button' + index).observe('click', function(event) {
            // Why does this always say "This is button 5" no matter
            // which button I click?
            alert("This is button " + index);
        });
    }

The reason this happens is that the function inside the loop is a
closure over the context in which it's created. Via the context it
receives a *reference* to the `index` variable, not its value. And so
it sees any changes to the value of `index` that may happen. All five
functions created all refer to the same variable, and all see the
*current* value of that variable when they're called.

There are a couple of ways of fixing this, all of which hinge on
making sure that you grab a copy of the *value* of `index` at a point
in time rather than a reference to it. To do that, you need to create
a new context for the function to close over, which means using
another function (since functions create contexts). Here's an example:

    var index;
    for (index = 0; index < 5; ++index) {
        hookButton(index);
    }
    function hookButton(buttonIndex) {
        $('button' + index).observe('click', function(event) {
            alert("This is button " + buttonIndex);
        });
    }

There we pass the *value* of `index` into `hookButton` and create the
callback within that new context. The callback closes over the
`buttonIndex` argument in the context for *that call* to `hookButton`,
which we don't change anywhere.

You can use Function#curry to do something similar:

    var index;
    for (index = 0; index < 5; ++index) {
        $('button' + index).observe('click', (function(buttonIndex,
event) {
            alert("This is button " + buttonIndex);
        }).curry(index));
    }

Function#curry creates a new function on the fly that, when called,
will call the original function passing in the arguments you gave
#curry as the first few arguments to the function. Of course, with
this approach we end up creating several temporary functions, whereas
the first approach only creates one function (and potentially not a
temporary one).

For your specific situation, I think the first approach is easiest to
apply -- just move the body of your loop into a separate function and
pass that function the value of `i` and the other things it needs. It
also leads to more modular code. :-)

HTH,
--
T.J. Crowder
Independent Software Consultant
tj / crowder software / com
www.crowdersoftware.com


On Jul 24, 6:31 am, Iqbal Hossain <iqbal....@gmail.com> wrote:
> Dear concern,
>
> It is quite difficult for me to describe my problem in written. So I
> attached a picture which can express clearly my problem regarding element
> array update with ajax.request.
>
> Looking for your kind solution.
>
> regards,
> Iqbal
>
>  problem.jpg
> 362KViewDownload

-- 
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptacul...@googlegroups.com.
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en.

Reply via email to