【问题标题】:OOP approach in js with ajax带有ajax的js中的OOP方法
【发布时间】:2014-08-14 16:27:56
【问题描述】:

... 嗨,我有一个对象:

function Page(daoService) {
    this.daoService = daoService;
    this.gamesList = this.daoService.getGamesList();
}

// Rendering thumbs for main page
Page.prototype.renderThumbs = function(idContainer){
    var container = document.getElementById(idContainer);
    for (var i = 0; i < this.gamesList.length; i++) {
        var thumbNode = document.createTextNode("<div class='thumbIcon'></div>");
        thumbNode.style.backgroundImage = Const.PATH_THUMBS + this.gamesList.gameTitleseo;
        container.appendChild(thumbNode);
    }
};

而且我的代码中有使用这个对象的函数:

document.onreadystatechange = function() { 
    if (document.readyState == "interactive") { 
        // Initialization of elements
        // Setting global dao service
        var daoService = AjaxService();

        // Initialization for page object
        var page = new Page(daoService);
        page.renderThumbs("homePageContainer");
    } 
} 

这里的问题是,当我调用 page.renderThumbs 时,字段 this.gamesList 仍然没有初始化,因为它没有从服务器获得 ajax 响应。你能帮我处理我需要改变的方法吗?谢谢

【问题讨论】:

  • 你必须在回调中调用 renderthumbs。即例如。在 ajax 的成功回调中调用函数。

标签: javascript ajax oop document-ready


【解决方案1】:

在返回异步结果时在您的 daoService 中使用承诺。 jQuery 有一个不错的 Promise 框架 符号代码:

function DaoService() {
   this.getGamesList = function() {
       return $.Deferred(function(defer) {
            //Do ajax request here and wait for callback/complete
            //replace DoAjax to your ajax or better yet use jQuery ajax that is already promise aware
            DoAjax(function onReady(result) {
                defer.resolve(result.data);    
            });

       }).promise();
   }
}

当您需要游戏列表时,在您的页面类中调用它,如下所示。它只会下载一次数据,以后每次都会使用已经下载的数据。

Page.prototype.renderThumbs = function(idContainer){
    var container = document.getElementById(idContainer);
    this.daoService.getGamesList().then(function(gamesList) {
       for (var i = 0; i < gamesList.length; i++) {
          var gameListItem = gamesList[i];
          //do your funky html concats or use some templating
       });
    });
    }
};

【讨论】:

  • 嗨,我有几个问题,我可以在没有其他库的原生 js 中使用 Promises 来做吗? DaoService 的感觉:它可以更改,例如,我想不是从 ajax 而是从我的页面(它之前加载过)获取数据,所以我需要更改我的 Page 类吗?或者我可以直接覆盖我的 dao 服务?
【解决方案2】:

您需要在 daoService 上设置 getGamesList 来处理异步方法。这是我的意思的粗略草图:

DaoService.prototype.getGamesList = function(callback) {

    var self = this;

    // Has the gamesList been populated by a previous call to this function?
    if (this.gamesList) {
        // The gamesList property has values, call the callback.
        callback(this.gamesList);
    }
    else {
        // The gamesList was not populated, make the ajax call.
        $.ajax('URL').done(function(data) {
            // Handle data coming back from the server.
            self.gamesList = data;
            callback(this.gamesList);
        });
    }


}

然后您可以像这样使用来自renderThumbs 的getGamesList 方法调用:

Page.prototype.renderThumbs = function(idContainer){
    var container = document.getElementById(idContainer);

    // The anonymous function will be called whether the list was
    // already populated in daoService or an ajax call is made.
    this.daoService.getGamesList(function(gamesList) {
        for (var i = 0; i < gamesList.length; i++) {
            var thumbNode = document.createTextNode("<div class='thumbIcon'></div>");
            thumbNode.style.backgroundImage = Const.PATH_THUMBS + gamesList[i].gameTitleseo;
            container.appendChild(thumbNode);
        }
    });
};

【讨论】:

  • if (this.gamesList) {...这里的“这个”是什么?这不是我的 Page.gamesList 不是吗?
  • 不,这将引用 daoService 上的 gamesList 属性。如果您不喜欢将它附加到 daoService 并且希望它位于 Page 对象上,则需要相应地调整以“缓存”Page 中的 gamesList。顺便说一句,我在ajax调用中错误地使用了this,我将修改代码。
猜你喜欢
  • 2015-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-15
  • 1970-01-01
  • 2012-05-17
  • 1970-01-01
相关资源
最近更新 更多