如何在ajax调用期间保持这个上下文(jquery + coffeescript)

时间:2011-12-18 14:09:58

标签: javascript jquery ajax coffeescript

我上课了:

class @GameMap
    options : {
        'width' : 100,
        'height' : 100,
        'tileWidth' : 45,
        'tileHeight' : 20,
        'scale' : 5,
        'moveDistance' : 100, #Distance to move with the map controlers
        'showErrorMessages' : true,
        'zindexDecorElementBase' : 99999,
        'zindexGroudElementBase' : 88888
    }

    lang : {
        'errContainerMissing' : "L'élement pour créer la carte n'existe pas"
    }

    constructor: (@element) ->
      this.run()

    run: ->
      this.loadDatas()

    loadDatas: (top,left) ->
      $.ajax(
          url: "/map/getnewcoord",
          data: {
             map_width : this.options.width,
             map_height : this.options.height,
             tile_height : this.options.tileHeight,
             tile_width : this.options.tileWidth,
             window_large : $('.map-windows').width(),
             window_height:  $('.map-windows').height(),
             top : top ,
             left : left
          },
          success: (data) ->
            $.each(data,(index,item) ->
              this.createTile(item.posX,item.posY);
            )
      )

    createTile: (m,n) ->
       #We are in the tile reference
       yDelta = Math.round((options.width ) * options.tileHeight );
       console.log('pass')

  $ ->
    gamemap = new GameMap("#map .block-map")

但是我收到了错误

  

this.createTile不是函数

这是因为“this”不是我班级的“this”,而是我的json调用返回的项目之一。

如何在ajax成功回调函数中保持我的班级“this”?

3 个答案:

答案 0 :(得分:3)

保留对this

的引用

很多人使用var that = this(或self等模式,如果它更适合你的话。)

然后,在您的内部函数中,将this的引用替换为that,这将是父函数this

或者,您可以使用$.proxy() ...

包装匿名函数定义
fn = $.proxy(fn, this);

...这将确保this内部始终是父this$.proxy()是实现bind()的跨浏览器方式(在旧版IE或Safari中未实现)。

答案 1 :(得分:3)

以下是CoffeeScript的方法:

      success: (data) =>
        $.each(data,(index,item) =>
          this.createTile(item.posX,item.posY);
        )

这编译成与alex的答案非常相似的东西,但我认为,它更具可读性。 =>运算符在使用定义时存在的this时定义函数,而不是在调用函数时定义函数。

虽然我们处于此状态,但您可能会发现使用@代替this更具可读性:

          @createTile(item.posX,item.posY);

答案 2 :(得分:1)

您可以将context作为参数传递给ajax()方法:

$.ajax({ /*...,*/ context: this/*, ...*/ });

http://api.jquery.com/jQuery.ajax/