2009-08-03 3 views
2

Я пытаюсь использовать Class методы prototype.js управлять моей иерархии объектов на моем текущем проекте, но у меня есть некоторые проблемы с этого ключевое слово в conjonction с класса .create.Class.create и это ключевое слово

Вот кусок старомодного Plain коды расслоения плотного создание наследования:

var Super1 = function() { 
    this.fu = "bar"; 
} 

var Sub1 = function() { 
    this.baz = "bat"; 
    this.f = function (e) { 
     alert("Sub1:"+this.fu+this.baz); 
    }.bindAsEventListener(this); 
    document.observe("click", this.f); 
}; 
Sub1.prototype = new Super1(); 
new Sub1(); 

И вот моя первая попытка имитируя это с Class.create:

var Super2 = Class.create({ 
    fu: "bar" 
}); 

var Sub2 = Class.create(Super2, { 
    baz: "bat", 
    f: function (e) { 
     alert("Sub2:"+this.fu+this.baz); 
    }.bindAsEventListener(this), 
    initialize: function() { 
     document.observe("click", this.f); 
    } 
}); 
new Sub2(); 

So далеко так хорошо ... Но, конечно, это не работает: f привязан к окну, а не к объекту, созданному с помощью новый. Единственный способ, который я нашел, это:

var Super3 = Class.create({ 
    fu: "bar" 
}); 

var Sub3 = Class.create(Super3, { 
    baz: "bat", 
    f: function (e) { 
     alert("Sub3:"+this.fu+this.baz); 
    }, 
    initialize: function() { 
     this.f = this.f.bindAsEventListener(this); 
     document.observe("click", this.f); 
    } 
}); 
new Sub3(); 

Но это действительно неэлегантно. Как я должен справиться с этим?

редактировать (ответить Colin):

  • мне нужно, чтобы связать е себя, так что я могу назвать stopObserving на е (см http://prototypejs.org/api/event/stopObserving)

  • I еще нужно bindAsEventListener каждый раз, когда мне нужно это внутри слушателя, так как по умолчанию это является элемент, который запускает событие (см http://prototypejs.org/api/event/observe)

  • Я все еще жду anwser на googlegroup :) Я вроде отправил сюда, чтобы увидеть, могу ли я получить быстрый ответ через С.О.

  • я мог (и, вероятно, должны) использовать привязку вместо bindAsEventListener. Я использовал последнее, чтобы было ясно, что я получаю слушателя. Это не меняет того факта, что процедура связывания неэлегантна.

+0

Re bindAsEventListener: вам нужно «привязать», чтобы установить «это», но единственная дополнительная вещь, которую дает вам «bindAsEventListener», уже обрабатывается «наблюдать», нет? –

+0

Да, вы правы. Однако проблема остается прежней, я использую bind или bindAsEventListener. – Alsciende

+0

Хорошо. Теперь я понимаю, что вы имели в виду с вашим первым «Кстати»: bindAsEventListener почти никогда не нужен «вместо связывания». Это правильно, насколько я могу судить, и я постараюсь это запомнить. – Alsciende

ответ

3

Вы почти получили его, просто не нужно его обновлять.е:

var Sub3 = Class.create(Super3, { 
    baz: "bat", 
    f: function() { 
     alert("Sub3:"+this.fu+this.baz); 
    }, 
    initialize: function() { 
     document.observe("click", this.f.bindAsEventListener(this)); 
     // You could also use .bind(), since you don't pass any 
     // other arguments to f 
    } 
}); 

Edit: В ответ на ваш комментарий, вы могли бы сделать что-то вроде этого (хотя это, возможно, как «некрасиво» в качестве примера):

var Sub3 = Class.create(Super3, { 
    baz: "bat", 
    initialize: function() { 
     this.f = function() { 
      alert("Sub3:"+this.fu+this.baz); 
     }.bind(this); 

     document.observe("click", this.f); 
    } 
}); 

Теперь вы можете использовать stopObserving с this.f. Когда вам нужно перерегистрировать прослушиватель, вы можете просто просто использовать this.f, так как он все равно будет привязан к тому же экземпляру, который использовался при инициализации.

+0

Как объяснялось ранее, мне нужно связать f, поэтому я могу вызвать stopObserving. – Alsciende

+0

Хорошо, код обновлен. Скажите мне, если вам это нравится, или если это слишком «уродливо» для вашего вкуса =) – PatrikAkerstrand

+0

@Machine верна в своей реализации – Josh

0

Я не слишком ясно, об этой области, но я думаю, что ответ (непроверенный):

var Sub3 = Class.create(Super3, { 
    baz: "bat", 
    f: function() { 
    alert("Sub3:"+this.fu+this.baz); 
    }, 
    initialize: function() { 
    document.observe("click", this.f.bind(this)); 
    } 
}); 

класс устраивает, инициализирующий называются методом объекта нового объекта, так «this» относится к новому объекту внутри «initialize», поэтому вам просто нужно привязать this.f к этому.

Кстати, bindAsEventListener почти никогда не нужен: Event.observe (и Element.observe) вызывает обработчик с событием в качестве первого аргумента в любом случае.

Между прочим, Prototype & Scriptaculous google group - очень полезный форум.

+0

Спасибо, Колин. Я отредактировал оригинальное сообщение, чтобы ответить вам. – Alsciende

Смежные вопросы