Как мне написать метод, который может быть запущен только один или несколько раз, но я хочу, чтобы некоторая логика запускалась только один раз при вызове метода? - PullRequest
2 голосов
/ 05 июля 2011

Странный вопрос, я знаю.Позвольте мне объяснить.

У меня есть функция javascript / jquery, которая используется для обработки изменений флажков.Вот некоторый псевдокод (к вашему сведению, я на самом деле не пытаюсь получить количество красных строк - это просто PSEUDO CODE):

$("input[type='checkbox'].option").change(function() {
    if ($(this).is(":checked")) {
        $("div.special").removeClass("red");
    }
    else {
        $("div.special").addClass("red");
    }

    // I only want to call this after all the checkbox event have been handled
    updateNumRedDivs();
});

function updateNumRedDivs() {
    alert($("div.special.red").length+"red DIVs found");
}

Теперь обработчик флажка можно вызывать либо когда отдельный человекфлажок установлен (очевидно), или когда вызывается отдельный флажок «Выбрать все»:

$(".myForm .selectAllCheckbox").change(function() {
    var $checkboxes = $(this).closest("form").find("input[type='checkbox'].option");

    if ($(this).attr("checked")) {
        $checkboxes.each(function() {
            if (!$(this).attr("checked"))
                $(this).attr("checked", "checked").change();
        });
    }

    updateNumRedDivs();
});

Надеюсь, это имеет смысл.Спасибо.

Ответы [ 5 ]

3 голосов
/ 05 июля 2011

Разделите логику для отдельного обработчика смены флажка на две функции.Затем, для выбора всего, просто вызовите нужную функцию, а не вызывайте change():

function changeHandler(chkBox) {
    if (chkBox.is(":checked")) {
        $("div.special").removeClass("red");
    }
    else {
        $("div.special").addClass("red");
    }
}
$("input[type='checkbox'].option").change(function() {
    changeHandler($(this));
    updateNumRedDivs();
});

function updateNumRedDivs() {
    alert($("div.special.red").length+"red DIVs found");
}

$(".myForm .selectAllCheckbox").change(function() {
    var $checkboxes = $(this).closest("form").find("input[type='checkbox'].option");

    if ($(this).attr("checked")) {
        $checkboxes.each(function() {
            if (!$(this).attr("checked"))
                changeHandler($(this).attr("checked", "checked"));
        });
    }

    updateNumRedDivs();
});
1 голос
/ 05 июля 2011

Если вы просто хотите, чтобы он запускался один раз, просто уничтожьте ссылку в нижней части функции.

var updateNumRedDivs = function() {
    // ... actual handling here
    updateNumRedDivs = function(){};
}

Несколько раз я бы использовал закрытие, например,

// This will run five times, before destroying
var updateNumRedDivs = function(amount) {
    var calls = 0;
    return function () {
        // handle event
        if (++calls === amount) updateNumRedDivs = function() {};
    };
}(5) 

Редактировать:
Возможно, ваше намерение неправильно понято с помощью функции, которая запускается один или несколько раз.Вы ищете функцию, которая запускается только один раз из каждого источника, или функцию, которая не будет ограничена общим количеством вызовов, а вместо этого будет n вызовов из одного источника?

0 голосов
/ 06 июля 2011

Я бы сделал это, передав дополнительные параметры событию изменения через trigger:

ПРИМЕЧАНИЕ: ошеломлен, чтобы проиллюстрировать идею.

http://jsfiddle.net/bnWVd/

function doit(){
    alert("done");   
}

$("input").click(function(event,extraParams){
    // do stuff
    if(extraParams && extraParams.noAlert){
       // do nothing or maybe something else
    }else{
        doit(); 
    }
});

$("button").click(function(){
    $("input").each(function(){
        $(this).trigger("click",{noAlert: true});
    }); 

    doit();
});

По сути, при вызове в цикле я передаю параметр событию, сообщая ему, что не нужно запускать дополнительную функцию. Затем, когда цикл завершен, я вызываю его напрямую. Если параметр не передан, он будет вызван.

0 голосов
/ 06 июля 2011

Слишком много кода Хорошо, вы не хотите, чтобы событие Изменить одиночного флажка срабатывало, когда вы выбираете флажок Выбрать ВСЕ

var SelectALLFired=false;

В обработчике SelectALLCheckBox установите значение для SelectALLFired = true; и после завершения измените значение обратно на SelectALLFired = false;

в функции Single CheckBox Change, прежде чем что-либо делать, напишите оператор If

if(!SelectALLFired)
{
Your Code
}

$(".myForm .selectAllCheckbox").change(function() {
SelectALLFired=true;
var $checkboxes = $(this).closest("form").find("input[type='checkbox'].option");

if ($(this).attr("checked")) {
    $checkboxes.each(function() {
        if (!$(this).attr("checked"))
            $(this).attr("checked", "checked").change();
    });
}
    SelectALLFired = false;

updateNumRedDivs();

})

$("input[type='checkbox'].option").change(function() {
if(!SelectALLFired)
{
   if ($(this).is(":checked")) {
       $("div.special").removeClass("red");
    }
    else {
       $("div.special").addClass("red");
    }
}
// I only want to call this after all the checkbox event have been handled
updateNumRedDivs();
});
0 голосов
/ 05 июля 2011

вот решение, которое я придумал - не очень, но оно выполняет свою работу:

$(".myForm input[type='checkbox']").change(function() {
    if ($(this).hasClass("selectAllCheckbox") {
        var $checkboxes = $(this).closest("form").find("input[type='checkbox'].option");

        if ($(this).attr("checked")) {
            $checkboxes.each(function() {
                if (!$(this).attr("checked"))
                    $(this).attr("checked", "checked").change();
            });
        }
    }
    else {
        if ($(this).is(":checked")) {
            $("div.special").removeClass("red");
        }
        else {
            $("div.special").addClass("red");
        }
    }

    updateNumRedDivs();
});

function updateNumRedDivs() {
    alert($("div.special.red").length+"red DIVs found");
}

По сути, я объединил в один обработчик изменений и сделал его рекурсивным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...