Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使javascript在OO背景下更易于阅读、维护和理解?_Javascript - Fatal编程技术网

如何使javascript在OO背景下更易于阅读、维护和理解?

如何使javascript在OO背景下更易于阅读、维护和理解?,javascript,Javascript,我来自Java、C#等国家。我正在为一个web应用程序开发一个javascript报告引擎。我正在使用jQuery、AJAX等。我很难让事情按我认为应该的方式运行——例如,我遇到了太多麻烦,无法确保在进行AJAX调用时,我的回调能够访问对象的成员。那些回调函数不需要那么复杂,是吗?我知道我一定做错了什么。请指出我可以做得更好的地方-如果提供的代码片段太多/太少/太可怕,请告诉我 我想做的是: 在页面加载时,我有一个选择全部用户 我创建报告(目前为1个)并将其添加到选择框中 当同时选择用户和报告

我来自Java、C#等国家。我正在为一个web应用程序开发一个javascript报告引擎。我正在使用jQuery、AJAX等。我很难让事情按我认为应该的方式运行——例如,我遇到了太多麻烦,无法确保在进行AJAX调用时,我的回调能够访问对象的成员。那些回调函数不需要那么复杂,是吗?我知道我一定做错了什么。请指出我可以做得更好的地方-如果提供的代码片段太多/太少/太可怕,请告诉我

我想做的是:

  • 在页面加载时,我有一个选择全部用户
  • 我创建报告(目前为1个)并将其添加到选择框中
  • 当同时选择用户和报告时,我运行报告
  • 该报告涉及到一系列的呼叫-获得练习系列赛、联赛和锦标赛-对于每个联赛和锦标赛,它获得所有这些系列赛,然后对于每个系列它获得所有比赛
  • 它维护活动呼叫的计数器,当所有呼叫都完成时,报告将运行并显示给用户
代码:

//初始化处理程序和报告
函数loadUI(){
loadReports();
$(“#用户选择”).change(更新按钮);
$(“#运行报告”)。单击(运行报告);
updateRunButton();
返回;
$(“#用户选择”).change(loadUserGames);
var user=$(“#userSelect”).val();
如果(用户){
getUserGames(用户);
}
}
//创建报告并将其添加到选择列表中
函数loadReports(){
var reportSelect=$(“#reportSelect”);
var报告=新的备用报告();
engine.reports[report.name]=报表;
reportSelect.append($(“”).text(report.name));
reportSelect.change(updateRunButton);
}
//表示我们现在可以运行的1报表的类。
函数SpareReport(){
this.name=“备用百分比”;
this.activate=函数(){
};
this.canRun=函数(){
返回true;
};
//收集报表的数据。初始化/重置类变量,
//并发起调用以检索所有用户练习、联赛和锦标赛。
this.run=函数(){
var rC=$(“#rC”);
var user=engine.currentUser();
html(“加载游戏…”);
这一点。pendingOperations=3;
这个.games=[];
$(“#运行报告”).enabled=false;
$.ajaxSetup({“错误”):(函数(报告){
返回函数(事件、XMLHttpRequest、ajaxOptions、thrownError){
report.ajaxError(事件、XMLHttpRequest、ajaxOptions、thrownError);
};
})(本条)});
$.getJSON(“/api/leagues”,{“user”:user},(函数(报告){
返回函数(联赛){
报告。addSeriesGroup(联赛);
};
})(本);;
$.getJSON(“/api/tournaments”,{“user”:user},(函数(报告){
返回函数(锦标赛){
报告。addSeriesGroup(锦标赛);
};
})(本);;
$.getJSON(“/api/practices”,{“user”:user},(函数(报告){
返回函数(实践){
报告。添加系列(实践);
};
})(本);;
};
//检索系列组的系列(ID组),如联盟或
//锦标赛。
this.addSeriesGroup=函数(seriesGroups){
var报告=此;
if(系列组){
$.each(系列组,函数(索引,系列组){
report.pendingOperations+=1;
$.getJSON(“/api/seriesgroup”,{“group”:seriesgroup.key},(函数(报告){
返回函数(系列){
报告。添加系列(系列);
};
})(报告);
});
}
这一点。pendingOperations-=1;
this.tryFinishReport();
};
//检索系列组的实际系列。采用一组
//序列ID并检索每个序列。
this.addSerieses=函数(serieses){
var报告=此;
if(系列){
$.each(系列、函数(索引、系列){
report.pendingOperations+=1;
$.getJSON(“/api/series”,{“series”:series.key},(函数(报告){
返回函数(系列){
报告.增补系列(系列);
};
})(报告);
});
}
这一点。pendingOperations-=1;
this.tryFinishReport();
};
//将该系列的游戏添加到游戏列表中
this.addSeries=函数(系列){
var报告=此;
if(系列和系列游戏){
$.each(系列.游戏,功能(索引,游戏){
报告。游戏。推(游戏);
});
}
这一点。pendingOperations-=1;
this.tryFinishReport();
};
//检查所有挂起的请求是否已完成-如果已完成,则运行
//报告。
this.tryFinishReport=函数(){
如果(this.pendingOperations>0){
返回;
}
var进度=$(“#报告进度”);
进度。文本(“执行计算…”);
setTimeout((函数(报告){
返回函数(){
report.finishReport();
};
})(本条第1款);
}
//执行报告计算并将其显示给用户。
this.finishReport=函数(){
var rC=$(“#rC”);
//剪下一页计算/表格生成
html(html),;
$(“#rC table”).addClass(“tablesorter”).attr(“cellspacting”,“1”).tablesorter({“sortList”:[[3,1]});
};
//处理错误(通过忽略错误)
this.ajaxError=函数(事件、XMLHttpRequest、ajaxOptions、thrownError){
这
//Initializes the handlers and reports
function loadUI() {
    loadReports();
    $("#userSelect").change(updateRunButton);
    $("#runReport").click(runReport);
    updateRunButton();
    return;
    $("#userSelect").change(loadUserGames);
    var user = $("#userSelect").val();
    if(user) {
        getUserGames(user);
    }
}

//Creates reports and adds them to the select
function loadReports() {
    var reportSelect = $("#reportSelect");
    var report = new SpareReport();
    engine.reports[report.name] = report;
    reportSelect.append($("<option/>").text(report.name));

    reportSelect.change(updateRunButton);
}

//The class that represents the 1 report we can run right now.
function SpareReport() {
    this.name = "Spare Percentages";
    this.activate = function() {

    };

    this.canRun = function() {
        return true;
    };

    //Collects the data for the report.  Initializes/resets the class variables,
    //and initiates calls to retrieve all user practices, leagues, and tournaments.
    this.run = function() {
        var rC = $("#rC");
        var user = engine.currentUser();
        rC.html("<img src='/img/loading.gif' alt='Loading...'/> <span id='reportProgress'>Loading games...</span>");
        this.pendingOperations = 3;
        this.games = [];
        $("#runReport").enabled = false;
        $.ajaxSetup({"error":(function(report) {
            return function(event, XMLHttpRequest, ajaxOptions, thrownError) {
                report.ajaxError(event, XMLHttpRequest, ajaxOptions, thrownError);
            };
        })(this)});

        $.getJSON("/api/leagues", {"user":user}, (function(report) {
            return function(leagues) {
                report.addSeriesGroup(leagues);
            };
        })(this));
        $.getJSON("/api/tournaments", {"user":user}, (function(report) {
            return function(tournaments) {
                report.addSeriesGroup(tournaments);
            };
        })(this));
        $.getJSON("/api/practices", {"user":user}, (function(report) {
            return function(practices) {
                report.addSerieses(practices);
            };
        })(this));
    };

    // Retrieves the serieses (group of IDs) for a series group, such as a league or
    // tournament.
    this.addSeriesGroup = function(seriesGroups) {
        var report = this;
        if(seriesGroups) {
            $.each(seriesGroups, function(index, seriesGroup) {
                report.pendingOperations += 1;
                $.getJSON("/api/seriesgroup", {"group":seriesGroup.key}, (function(report) {
                    return function(serieses) {
                        report.addSerieses(serieses);
                    };
                })(report));
            });
        }
        this.pendingOperations -= 1;
        this.tryFinishReport();
    };

    // Retrieves the actual serieses for a series group.  Takes a set of
    // series IDs and retrieves each series.
    this.addSerieses = function(serieses) {
        var report = this;
        if(serieses) {
            $.each(serieses, function(index, series) {
                report.pendingOperations += 1;
                $.getJSON("/api/series", {"series":series.key}, (function(report) {
                    return function(series) {
                        report.addSeries(series);
                    };
                })(report));
            });
        }
        this.pendingOperations -= 1;
        this.tryFinishReport();
    };

    // Adds the games for the series to the list of games
    this.addSeries = function(series) {
        var report = this;
        if(series && series.games) {
            $.each(series.games, function(index, game) {
                report.games.push(game);
            });
        }
        this.pendingOperations -= 1;
        this.tryFinishReport();
    };

    // Checks to see if all pending requests have completed - if so, runs the
    // report.
    this.tryFinishReport = function() {
        if(this.pendingOperations > 0) {
            return;
        }
        var progress = $("#reportProgress");
        progress.text("Performing calculations...");
        setTimeout((function(report) {
            return function() {
                report.finishReport();
            };
        })(this), 1);
    }

    // Performs report calculations and displays them to the user.
    this.finishReport = function() {
        var rC = $("#rC");

        //snip a page of calculations/table generation
        rC.html(html);

        $("#rC table").addClass("tablesorter").attr("cellspacing", "1").tablesorter({"sortList":[[3,1]]});
    };

    // Handles errors (by ignoring them)
    this.ajaxError = function(event, XMLHttpRequest, ajaxOptions, thrownError) {
        this.pendingOperations -= 1;
    };

    return true;
}

// A class to track the state of the various controls.  The "series set" stuff
// is for future functionality.
function ReportingEngine() {
    this.seriesSet = [];
    this.reports = {};
    this.getSeriesSet = function() {
        return this.seriesSet;
    };
    this.clearSeriesSet = function() {
        this.seriesSet = [];
    };
    this.addGame = function(series) {
        this.seriesSet.push(series);
    };
    this.currentUser = function() {
        return $("#userSelect").val();
    };
    this.currentReport = function() {
        reportName = $("#reportSelect").val();
        if(reportName) {
            return this.reports[reportName];
        }
        return null;
    };
}

// Sets the enablement of the run button based on the selections to the inputs
function updateRunButton() {
    var report = engine.currentReport();
    var user = engine.currentUser();
    setRunButtonEnablement(report != null && user != null);
}

function setRunButtonEnablement(enabled) {
    if(enabled) {
        $("#runReport").removeAttr("disabled");
    } else {
        $("#runReport").attr("disabled", "disabled");
    }

}

var engine = new ReportingEngine();

$(document).ready( function() {
    loadUI();
});

function runReport() {
    var report = engine.currentReport();
    if(report == null) {
        updateRunButton();
        return;
    }
    report.run();
}
var x = 1;
$.ajax({
  success: function () {
    alert(x);
  }
});
$.getJSON("/api/leagues", {"user":user}, (function(report) {
        return function(leagues) {
            report.addSeriesGroup(leagues);
        };
    })(this));
var self = this;
$.getJSON("/api/leagues", {"user":user}, (function(leagues) {
            self.addSeriesGroup(leagues);
        });
function Parent(x) {
  this.x = x;  /* Set an instance variable. Methods come later. */
}

/* Make Parent inherit from Object by assigning an
 * instance of Object to Parent.prototype. This is
 * very different from how you do inheritance in
 * Java or C# !
 */
Parent.prototype = {  /* Define a method in the parent class. */
  foo: function () {
    return 'parent ' + this.x;  /* Use an instance variable. */
  }
}

function Child(x) {
  Parent.call(this, x)  /* Call the parent implementation. */
}

/* Similar to how Parent inherits from Object; you
 * assign an instance of the parent class (Parent) to
 * the prototype attribute of the child constructor
 * (Child).
 */
Child.prototype = new Parent();

/* Specialize the parent implementation. */
Child.prototype.foo = function() {
  return Parent.prototype.foo.call(this) + ' child ' + this.x;
}

/* Define a method in Child that does not override
 * something in Parent.
 */
Child.prototype.bar = function() {
  return 'bar';
}

var p = new Parent(1);
alert(p.foo());

var ch = new Child(2);
alert(ch.foo());
alert(ch.bar());