Javascript应用程序:糟糕的设计使得数百个ajax调用

时间:2014-09-30 01:27:09

标签: javascript jquery ajax fullcalendar

我在论坛上就我在申请中遇到的问题提出了question。虽然问题被标记为重复,但我尝试使用良好实践来解决问题。 经过深思熟虑,我的代码完成了工作,但不是我预期的方式。 我正在使用Fullcalendar插件制作应用程序。在对日历中的每个事件执行的“eventRender”回调中,我所做的回调是进行数百个ajax调用:@ 我想我对所有回调的事情都不太了解。 这是我的代码:

    $().ready(function() {
        var obterDadosCategorias = (function() {
            var dadosCategorias;

            var efetuarPost = function(callback){
                $.post(
                    "{{ baseRoute }}/cadastro/categoria/listar"
                    , {
                        "ajax": "true"
                    }
                ).done(function(data) {
                    var obj = $.parseJSON(data);
                    if (obj.result) {
                        callback(obj.data);
                    } else {
                        alert('Erro interno: não foi possível obter os dados das categorias');
                    }
                }).fail(function(){
                    alert('Erro interno: não foi possível obter os dados das categorias');
                });
            };

            return function(callback) {
                if (dadosCategorias) {
                    callback(dadosCategorias);
                    return;
                }

                efetuarPost(function(dados) {
                    dadosCategorias = dados;
                    callback(dados);
                });
            };
        })();

        $("#fullcalendar").fullCalendar({
            "eventRender": function(event, element, view) {
                if (view.name === "month") {
                    var beforeMonth = parseInt(event.end.format("YYYYMMDD")) < parseInt(view.intervalStart.format("YYYYMMDD"));
                    var afterMonth = parseInt(event.start.format("YYYYMMDD")) > parseInt(view.intervalEnd.clone().subtract(1, 'days').format("YYYYMMDD"));

                    if (beforeMonth || afterMonth) {
                        return false;
                    }
                }

                obterDadosCategorias(function(dadosCategorias) {
                    $(element).css("background-color", dadosCategorias["id_" + event.categoria].cor).css("color", textoBrancoOuPreto(dadosCategorias["id_" + event.categoria].cor));
                });

                return $(element);
            }
        });
    });

希望你们能帮助我。 :d 提前谢谢。

1 个答案:

答案 0 :(得分:2)

使用异步代码需要您以不同的方式思考如何构建函数。而不是思考:“我需要编写一个返回值的函数”,你应该考虑“我需要编写一个函数,一旦我有一个值就执行一个动作。”

看来你只需要一个AJAX调用即可获得你的类别列表。您每次在日历上呈现事件时都会发出AJAX请求。相反,您应该获取一次类别,然后在检索后初始化您的日历。

另一个关键是存储可在renderEvent处理程序中访问它们的类别。我使用JavaScript Closures解决了这个问题,但您也可以使用全局变量(最好是命名空间)。

我相信这段代码可以完成你想要的一切:

$(document).ready(function() {  

    $.post(
        "{{ baseRoute }}/cadastro/categoria/listar"
        , {
            "ajax": "true"
        }
    ).done(function(data) {
        $("#fullcalendar").fullCalendar({
            "eventRender": createRenderEvent($.parseJSON(data))
        });

    }).fail(function(){
        alert('Erro interno: não foi possível obter os dados das categorias');
    });

    function createRenderEvent(dadosCategorias) {
        return function(event, element, view) {
            if (view.name === "month") {
                var beforeMonth = parseInt(event.end.format("YYYYMMDD")) < parseInt(view.intervalStart.format("YYYYMMDD"));
                var afterMonth = parseInt(event.start.format("YYYYMMDD")) > parseInt(view.intervalEnd.clone().subtract(1, 'days').format("YYYYMMDD"));

                if (beforeMonth || afterMonth) {
                    return false;
                }
            }

            $(element).css("background-color", dadosCategorias["id_" + event.categoria].cor).css("color", textoBrancoOuPreto(dadosCategorias["id_" + event.categoria].cor));
            return $(element);
        }
    }

});