2013-03-10 2 views
1

У меня есть простой класс, коробка:Coffeescript - Почему атрибуты моего класса undefined onclick?

class Box 
    constructor: (@idx, grid) -> 
     console.log("constructing", @idx) 
     @elem = document.createElement("div") 
     @elem.id = "box" + idx 
     @elem.className = "box" 
     @elem.onclick = @toggle 
     grid.appendChild(@elem) 

    toggle:() -> 
     alert("click") 
     console.log("My idx is: ", @idx) 

Когда конструктор запускает его отчеты «построение 0», «строительство 1» и т.д., так что я знаю, атрибут класса определяются. И если я вызываю b.toggle() (где b - экземпляр ящика), тогда он правильно сообщает idx. Но как только я нажимаю на элемент на странице, он говорит, что @idx не определен.

Так что кажется, что атрибуты коробки теряются в непосредственной близости от вещей. Почему это?

Вот скомпилированного JavaScript:

Box = (function() { 

    function Box(idx, grid) { 
    this.idx = idx; 
    console.log("constructing", this.idx); 
    this.elem = document.createElement("div"); 
    this.elem.id = "box" + idx; 
    this.elem.className = "box"; 
    this.elem.onclick = this.toggle; 
    grid.appendChild(this.elem); 
    } 

    Box.prototype.toggle = function() { 
    alert("click"); 
    return console.log("My idx is: ", this.idx); 
    }; 

    return Box; 

})(); 

Спасибо!

ответ

4

Использование fat arrow для toggle определения метода, чтобы привязать его к правильному контексту (ваш класс, например, в данном случае):

toggle: => 
    alert("click") 
    console.log("My idx is: ", @idx) 
+0

спасибо, что сработал. – dandelion

4

nl_0 имеет хороший ответ для решения. Но в конце javascript, вот почему это не получилось очень хорошо.

Box функция, которая строит Box объекты придает функцию toggle прототип элемента этой строки кода:

this.elem.onclick = this.toggle; 

В результате, когда внутри функции toggle, все, что доступно является элементом что к событию прилагается. Так, this внутри toggle - elem, и именно поэтому вы не видите на нем .idx.

+0

Итак, если бы у меня был код this.this.toggle, это сработало бы? – dandelion

+0

@danmane - HTMLElement не имеет определенного свойства 'this'. Для того, чтобы область «this' была такой же, как« Box »в этом смысле, тогда функция должна была быть определена в конструкторе, а« this »нужно было бы кэшировать в переменной, обычно называемой« self » '. –

+0

Вижу, спасибо! (10char) – dandelion

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