Как использовать requestAnimationFrame с объектом TypeScript?

у меня есть объект, который я хочу сделать рисунок на холст. Он будет использовать requestAnimationFrame начать игровой цикл:

в Contoso.ТС

class Contoso
{
   //private ctx: CanvasRenderingContext2D;

   Initialize(ctx: CanvasRenderingContext2D) {
      //this.ctx = ctx;
      Render();
   }

   Render() {
      //...snip doing any actual drawing for the purpose of this question
      requestAnimationFrame(this.Render);
   }
}

app.ТС

var contoso: Contoso;

contoso = new Contoso();
contoso.Initialize(canvas);

первый раз, когда кто-то называет Initialize на requestAnimationFrame удается правильно назвать Render.

второй раз requestAnimationFrame звонки Render, the this.Render и undefined и она падает.

это почти как если бы объект был уничтожен после первоначального вызова Initialize.

что происходит?

4 ответов


ты проиграл this контексте. Два возможных исправления:

class Contoso
{
   /* ... */

   // Use () => syntax so Render always gets 'this' context
   // from the class instance
   Render = () => {
      //...snip doing any actual drawing for the purpose of this question
      requestAnimationFrame(this.Render);
   }
}

альтернативное исправление, вероятно, немного яснее, но имеет обратную сторону создания намного больше распределений (вы, вероятно, не хотите выделять 1 закрытие на кадр!)

   Render() {
      //...snip doing any actual drawing for the purpose of this question
      requestAnimationFrame(() => this.Render);
   }

используйте синтаксис стрелки (лямбда):

requestAnimationFrame(() => this.Render());

вот статья в блоге, объясняющая больше об особенностях этого трюка:

http://www.anotherchris.net/typescript/using-the-this-keyword-with-typescript-and-a-jquery-function/


в Firefox 49.0.1 у меня есть сообщение об ошибке с помощью решения Ryan Cavanaugh.

SyntaxError: плохое определение метода

строку :

Render = () = > {

работа вокруг я нашел выглядит так :

class Test{

    constructor(){

        this.Render = ()=> {
            requestAnimationFrame( this.Render );
        };

    }
}

лучший подход, который я нашел.

requestAnimationFrame(this.Render.bind(this));

.bind(this) создает новую функцию, которая имеет свой this ключевое слово установлено в предоставленное значение.

Бонус Чтение