是否可以在Coffeescript中使用AJAX调用初始化变量

时间:2013-11-07 05:06:33

标签: javascript jquery ruby-on-rails ajax coffeescript

我有一个ajax调用,它通过命中我的控制器获取一些JSON:

class @Team
  constructor: () ->
    @players = null
    @getTeamInfo()

getTeamInfo:(teamId) ->
  request = $.ajax
  dataType: 'json',
  type: 'GET'
  url: "http://localhost:4000/teams/#{teamId}",
  async: false
  success : (data) =>
    _.each(data.players, (value) ->
      name = _.pluck(value, 'name')
      @players.push(new Player(name)))

问题在于我从一开始就需要玩家,并且,看到JS如何异步运行,变量为空。有没有办法用ajax调用实际初始化变量?

更新: 在从@mu_is_too_short获得关于该问题的新观点并理解来自@Rich Peck的ajax调用后回调的真正重要性之后,我能够通过确保依赖于从Ajax返回的数据的所有代码来初始化我的游戏call被包含在Ajax成功回调中。我想我可能需要包含构建游戏所需的所有数据,而不仅仅是团队和玩家数据。但那是后来的事。谢谢,伙计们。

class @Game

  constructor: (homeId, awayId) ->
    @homeTeam = new Team()
    @awayTeam = new Team()
    @display  = new GameDisplay()
    @pitcher  = new Pitching()
    @contact  = new Contact()
    @baseRunners = new BaseRunners()
    @gameEngine  = new GameEngine(@homeTeam, @awayTeam, @display, @pitcher, @contact, @baseRunners)
    @initializeHomeBattingOrder(1, 3)

  pitch: ->
    @gameEngine.makePitch()

  initializeHomeBattingOrder: (homeId, awayId) ->
    $.ajax
      dataType: 'json',
      type: 'GET',
      url: "http://localhost:4000/teams/#{homeId}",
      success : (data) =>
        @populateHomePlayers(data)
        @initializeAwayBattingOrder(awayId)

  initializeAwayBattingOrder: (awayId) ->
    $.ajax
      dataType: 'json',
      type: 'GET',
      url: "http://localhost:4000/teams/#{awayId}",
      success : (data) =>
        @populateAwayPlayers(data)
        @display.battingOrder(@awayTeam.players, @homeTeam.players)
        @display.teamsPlaying(@awayTeam.name, @homeTeam.name)

  populateHomePlayers: (data) ->
    @homeTeam.players = _.map(_.pluck(data.players, "name"), (name) -> new Player(name))
    @homeTeam.name = data.name

  populateAwayPlayers: (data) ->
    @awayTeam.players = _.map(_.pluck(data.players, "name"), (name) -> new Player(name))
    @awayTeam.name = data.name

1 个答案:

答案 0 :(得分:4)

我打算把它写成评论,但我认为在答案中读起来会更容易。如果不合适,我会删除,因为我认为我不能提供直接的解决方案,而是更多关于使用Ajax的信息


异步Javascript和XML

Ajax默认设置为异步运行,如果被迫同步运行(通过使用async: false

,实际上会冻结浏览器

我们发现这很困难,因为我们试图找到一种方法来使用它来调用一些变量&发现你不能“只使用ajax” - 你必须设计围绕


使用Ajax回调

我们想要呈现一个表单“on the fly”,它需要Ajax调用数据。问题是,我们不得不将Ajax放入现有代码中,而是重构它,以便代码的Ajax部分独立地运行到“静态”部分。我们通过using ajax callbacks

修复了它

这是我们的代码:

 function create_modal(o){

                //o.ajax = the link to use. If present, it means we use Ajax :)

            if(o.ajax){
            //Loading

            fetch_modal(o.ajax, function(data){

                var modal = document.createElement("div");
                modal.setAttribute("id", o.modal_id.substring(1));
                modal.className = 'modal ajax'; 
                modal.innerHTML = data;

                $("body").append(modal);
                overlay();
                show_modal(o);

            }, function(data){
                //error
            });
        }else{
            overlay();
            show_modal(o);
        }
}

function fetch_modal(link, success, error) {
    $.ajax({
        url: link,
        success: function(data) { success(data); },
        error: function(data)   { error(data); }
    });
}

你可以在http://emailsystem.herokuapp.com看到这个工作的演示(注册&然后点击“新列表”/“新广播”/“新用户”按钮) - 该表格通过ajax呈现


除了CoffeeScript格式之外,我认为你能做的最好的事情是为Ajax使用回调函数,并使Ajax成为你函数的核心组件,如下所示:

class @Team
  constructor: () ->
    @players = null
    @getTeamInfo(teamId, ->

      _.each(data.players, (value) ->
      name = _.pluck(value, 'name')
      @players.push(new Player(name)))
    , -> 
      //error


getTeamInfo:(teamId, success, error) ->
  request = $.ajax
  dataType: 'json'
  type: 'GET'
  url: "teams/#{teamId}"
  success : (data) => success(data)
  error : (data) => error(data)