Black Friday = Pricewatch Bekijk onze selectie van de beste Black Friday-deals en voorkom een miskoop.
Toon posts:

[ASP.NET AJAX] $addHandler en this

Pagina: 1
Acties:

Verwijderd

Topicstarter
Beste tweakers,

Ik heb een javascript class gemaakt met prototype waar ik een aantal events in heb zitten, hier is een simpele versie van de class:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var EventTest = function(value)
{
    this._value = value;
};

EventTest.prototype =
{
    initialize: function()
    {
        $addHandler(document, "click", this._onSayHello);
    },

    dispose: function()
    {
        $removeHandler(document, "click", this._onSayHello);
    },

    _onSayHello: function(e)
    {
        alert(this._value);
    }
};


In _onSayHello is 'this' niet meer het object maar iets anders (het htmldocument)

Ik kan nu wel elke keer een functie eromheen schrijven zoals:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
sayHello: function()
{
    var self = this;

    function onSayHello(e)
    {
        alert(self._value);
    }

    $addHandler(document, "click", onSayHello);
}


Maar dan kan ik net zo goed alles in closure schrijven en heel het microsoft ajax framework niet gebruiken. Ik ben al verschillende keren tegen dit soort problemen aangelopen en al deze problemen heb je geen last van als je alles met closure opbouwt, bovendien is de code dan ook nog een stuk beter te lezen.

Weet iemand de rede waarom microsoft er voor gekozen heeft om prototypes te gaan gebruiken imp. closure? in het begin toen het nog atlas hete was het volgens mij wel allemaal closure.

De call methode gebruik ik ook liever niet om dit op te lossen. Ik ben opzoek naar een nette oplossing.

[ Voor 0% gewijzigd door Verwijderd op 16-10-2008 17:54 . Reden: foutje in code ]


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:27

crisp

Devver

Pixelated

Gebruik dan een helper functie die de closure voor je regelt; geleend van prototype.js:
JavaScript:
1
2
3
4
5
6
7
8
9
Function.prototype.bind = function()
{
    var handler = this, args = [].slice.call(arguments, 0), object = args.shift();

    return function()
    {
        return handler.apply(object, args.concat([].slice.call(arguments, 0)));
    }
}

en dan simpelweg:
JavaScript:
1
2
3
4
initialize: function()
{
    $addHandler(document, "click", this._onSayHello.bind(this));
}


btw, door prototype compleet te initialiseren overschrijf je wel de constructor property.

Intentionally left blank


Verwijderd

Topicstarter
Dan zou ik zowel het microsoft frame work als het prototype framework moeten gebruiken, is dat niet een beetje dubbel op?

Maar waarom zit iedereen zo moeilijk te doen met prototype als het in closure allemaal gewoon werkt? het enige voordeel van prototype classes is dat ze sneller aangemaakt worden maar als gebruiker merk je daar weinig van tenzij er heel veel objecten tegelijkertijd aangemaakt worden.

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:27

crisp

Devver

Pixelated

Verwijderd schreef op maandag 13 oktober 2008 @ 21:53:
Dan zou ik zowel het microsoft frame work als het prototype framework moeten gebruiken, is dat niet een beetje dubbel op?
Nee, je hebt het prototype framework helemaal niet nodig, alleen de helper functie zoals ik die hierboven postte ;)
Maar waarom zit iedereen zo moeilijk te doen met prototype als het in closure allemaal gewoon werkt? het enige voordeel van prototype classes is dat ze sneller aangemaakt worden maar als gebruiker merk je daar weinig van tenzij er heel veel objecten tegelijkertijd aangemaakt worden.
Je geeft het antwoord zelf al: prototyped methods zijn efficienter als je veel instances van een object aanmaakt omdat niet elk object dan z'n eigen kopieset van methods heeft. Daarbij kan je ook aan overerving doen:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function Car()
{
    this.maxSpeed = 100;
}
Car.prototype.vroem = function()
{
    alert('Driving at ' + this.maxSpeed + ' miles per hour');
}

function SuperCar()
{
    this.maxSpeed = 200;
}
SuperCar.prototype = new Car();

var yourCar = new Car();
var myCar = new SuperCar();

yourCar.vroem();
myCar.vroem();

[ Voor 18% gewijzigd door crisp op 13-10-2008 22:02 ]

Intentionally left blank


Verwijderd

Topicstarter
Oh sorry ik las je reply niet goed :P

In dat geval is dat nog wel een mooie oplossing, bedankt!

Met closure kan je ook overerving doen trouwens

Verwijderd

Topicstarter
Ben er nog even verder gaan met het zoeken naar mogelijke oplossingen en heb een manier gevonden die volgens mij intern ongeveer het zelfde doet als die method van prototype alleen dit zit standaard in het ajax framework van ms ingebouwd.

De class ziet er nu zo uit:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
            var EventTest = function(value)
            {
                this._value = value;
            };

            EventTest.prototype =
            {
                initialize: function()
                {
                    this._clickDelegate = Function.createDelegate(this, this._onSayHello);
                    $addHandler(document, "click", this._clickDelegate);

                    console.log("initialized");
                },

                dispose: function()
                {
                    $removeHandler(document, "click", this._clickDelegate);
                    delete this._clickDelegate;

                    console.log("disposed");
                },

                _onSayHello: function(e)
                {
                    alert(this._value);
                }
            };

            var e = new EventTest("test");
            e.initialize();

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:27

crisp

Devver

Pixelated

createDelegate zal ongetwijfeld ongeveer hetzelfde doen ja ;)

Intentionally left blank

Pagina: 1