1

我有一个 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 调用包含在 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
4

1 回答 1

4

我打算将其写为评论,但我认为在答案中更容易阅读。如果不合适,我将删除,因为我认为我无法提供直接的解决方案,而是提供有关使用 Ajax 的更多信息


异步 Javascript 和 XML

Ajax 被设计为默认异步运行,如果它被迫同步运行,实际上会冻结你的浏览器(通过使用async: false

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


在 Ajax 中使用回调

我们想“即时”渲染一个表单,这需要 Ajax 调用数据。问题在于,我们不能仅仅将 Ajax 安装到现有代码中,而是必须对其进行重构,以便代码的 Ajax 部分独立于“静态”部分运行。我们通过使用 ajax 回调来修复它

这是我们的代码:

 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)
于 2013-11-07T10:10:48.257 回答