Вопрос

Я пытаюсь использовать библиотеку диалоговых окон предупреждений jQuery из http://abeautifulsite.net/notebook/87 вместо оповещений по умолчанию (которые, на мой взгляд, выглядят довольно ужасно).Кажется, это отличная библиотека, но нет примера использования библиотеки jConfirm.

Мне нужно сделать что-то вроде этого:

function confirm() {
        var result = false;
        var response = false;
        jConfirm('are you sure?', 'Confirmation Dialog',
          function(r) {
            result = r;
            response = true;
            return r;
        });
        if (response == true) {
            alert(result);
            return result;
        }
        else {
            //wait for response
            alert('hi');
        }
    }

и мой звонок с моей кнопки .net:

Я разместил комментарий на веб-сайте плагина (только сегодня утром), выполнил поиск в Google по запросу javascript и ждал завершения обратного вызова, но безрезультатно.

Есть идеи о том, как правильно использовать обратный вызов, чтобы получить результат до выполнения остальной части javascript?

Спасибо.

Это было полезно?

Решение

jConfirm('are you sure?', 'Confirmation Dialog',
    function(r) {
        result = r;
        response = true;
        return r;
    }
);
if (response == true) {

Это свидетельствует о неправильном понимании последовательности событий, происходящих при использовании асинхронного кода.Тот факт, что вы написали его встроенным, не означает, что он будет выполняться строго сверху вниз.

  1. jConfirm вызывается, получая в качестве одного из параметров функцию, которую он запоминает.
  2. jConfirm отображает свой пользовательский интерфейс на странице и немедленно возвращается.
  3. Строка if (response==true) выполняется.На самом деле это должно читаться просто как «если (ответ)», логическое сравнение является излишним.Но в любом случае ответ, конечно, ложный.Ваша функция сдается и завершает работу, возвращая управление браузеру.
  4. Пользователь щелкает пользовательский интерфейс jConfirm.
  5. jConfirm только сейчас приступает к действию и вызывает функцию, которую вы ему дали и которую он запомнил ранее.
  6. Ваша вложенная функция устанавливает ответ true, слишком поздно, чтобы условие if (response==true) могло что-либо с ним сделать.

В качестве альтернативы вы написали «//ожидание ответа», но вы не можете написать код JavaScript, который действительно это сделает.Ваша функция должна вернуться, чтобы вернуть управление браузеру, прежде чем браузер сможет запустить события щелчка в пользовательском интерфейсе jConfirm, которые продолжат обработку.

Существуют способы заставить асинхронный код работать в синхронном контексте (и наоборот) - в частности, потоки и сопрограммы (и их генераторы ограниченных отношений).Но в JavaScript нет ни одной из этих функций, поэтому вы должны писать свой код так, чтобы он соответствовал синхронной или асинхронной модели, которую использует ваша библиотека.

Другие советы

Вы только что столкнулись с большим ограничением в JavaScript.Как только ваш код попадает в асинхронный мир, у него нет возможности вернуться к классическому процедурному потоку выполнения.

В вашем примере решением было бы создать цикл, ожидающий заполнения ответа.Проблема в том, что JavaScript не предоставляет никаких инструкций, которые позволили бы вам выполнять бесконечный цикл, не задействуя при этом 100% вычислительной мощности.Таким образом, вы в конечном итоге заблокируете браузер, иногда до такой степени, что ваш пользователь не сможет ответить на реальный вопрос.

Единственное решение здесь — придерживаться асинхронной модели и сохранять ее.Мой совет: вам следует добавлять обратный вызов к любой функции, которая должна выполнять некоторую асинхронную работу, чтобы вызывающая сторона могла выполнить что-то в конце вашей функции.

function confirm(fnCallback) 
{
    jConfirm('are you sure?', 'Confirmation Dialog', function(r) 
    {
        // Do something with r 

        fnCallback && fnCallback(r); // call the callback if provided
    });
}

// in the caller

alert('begin');

confirm(function(r)
{
    alert(r);

    alert('end');
})

Поскольку обратный вызов является асинхронным (по крайней мере, в том смысле, что он ожидает, что пользователь что-то сделает), возможно, будет проще обработать то, что вам нужно, внутри обратного вызова:

function confirm() {
    jConfirm('are you sure?', 'Confirmation Dialog', function(r) {
        if (r) doSomething();
    });
}

@klogan [комментарии]

Я предполагаю, что вы получили это от здесь?

Страница дает вам ответ:(смотрите под Применение)

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


@klogan

Я пытаюсь подчеркнуть, что на самом деле не существует простого способа добиться того, чего вы хотите.Вы пытаетесь сопоставить процедурный и управляемый событиями программирование — то, в чем JavaScript вам не поможет.

Самый простой (хотя рискованный) Решением является использование псевдобесконечного цикла.Но если callback никогда не вызывается, теперь у вас есть настоящий бесконечный цикл.И, в зависимости от движка JavaScript, вы можете остановить ожидание браузера.

Точка: Лучше всего избегать этот пытаясь превратить событийно-ориентированный подход в процедурный.

function confirm() {
    var result = false;
    var response = false;

    jConfirm('are you sure?', 'Confirmation Dialog',
      function(r) {
        result = r;
        response = true;
    });

    while(!response) continue; // wait
    return result;
}

Технически, да, но я бы не стал делать это на веб-сайте.

Взгляни на Повествовательный JavaScript, который основан на Нарцисс.

Повествовательный JavaScript — это небольшое расширение языка JavaScript, которое позволяет блокировать возможности обратных вызовов асинхронных событий.Это делает асинхронный код легко читаемым и понятным.

Селен использует эту технологию.


Обновлять

Проверить Пряди JavaScript:

JavaScript Strands добавляет поддержку Coroutine и Cooperative Threading в язык JavaScript, чтобы обеспечить возможности блокировки для асинхронных обратных вызовов событий.Это делает код, который использует асинхронную работу гораздо более линейной, читаемой и управляемой.Strands построен на повествовательном JavaScript, написанном Neil Mix, и большая часть повествовательного JavaScript осталась в прядях, включая большую часть этой документации.

В JavaScript ваш код не может просто подождать, пока событие не будет запущено - событие всегда должно быть обработано отдельным, асинхронным обработчиком событий.Иногда это нормально, но это часто заставляет то, что должно быть простой последовательности утверждений в резких искажениях.Он также нарушает возможность инкапсулировать функциональность, потому что вызовые функции должны знать, чтобы обеспечить обработчик обратного вызовов.Strands обеспечивает возможность приостановить и возобновить потоки выполнения.Исполнение может приостановить резюме, когда событие будет завершено.Это позволяет вам писать трудную асинхронную обработку событий в простом, линейном, читаемом коде, который инкапсулирует реализацию.

Я предполагаю, что вам придется получить такой ответ.Я не думаю, что вам нужен обратный звонок.

function confirm() {
        var response = jConfirm('are you sure?', 'Confirmation Dialog');
        if (response) {
            alert(result);
        }
        else {
            //wait for response
            alert('hi');
        }
    }

Я думаю, что нашел возможное решение этой проблемы.Я читал эту статью:http://treasure4developer.wordpress.com/2008/06/23/calling-postback-event-from-javascript/

По сути, идея состоит в том, что вы принудительно выполняете обратную передачу из javascript. Сначала я обнаружил, что обратная передача будет работать, но не будет вызывать событие моей кнопки, но после прочтения статьи я обнаружил, что могу определить, была ли это обратная передача javascript, и просто вызвать метод обработки

С уважением DotnetShadow

Как чуваки сказали, пути нет!но...как мы говорим в моей стране (Бразилия), le gambi:

мы можем сделать что-то вроде этого:

<h:commandLink styleClass="linkValor xExcluir" value="x"  
                     onclick="if(confirmar('Confirmar excluir.','Deseja realmente excluir este registro?', this)) return true; else return false;"
                     action="#{mBeanPesquisarLinhas.excluir}"/>

и яваскрипт:

function confirmar(titulo, msg, elemento) { 

    if ($(elemento).attr('sim')) {      
        $(elemento).removeAttr('sim');      
        return true;
    } else if ($(elemento).attr('nao')) {       
        $(elemento).removeAttr('nao');      
        return false;
    } else {
        $("#dialog-confirm").html('<p>' + msg + '</p>').dialog({
            resizable : false,
            height : 200,
            modal : true,
            title : titulo,
            buttons : {
                "Sim" : function() {
                    $(this).dialog("close");
                    $(elemento).attr('sim', 'sim');
                    $(elemento).click();
                },
                "Não" : function() {
                    $(this).dialog("close");
                    $(elemento).attr('nao', 'nao');
                    $(elemento).click();
                }
            }
        });
    }

    return false;
}

это та же проблема, но с использованием jquery-ui.

Пока, и я надеюсь, что это может кому-нибудь помочь.

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

Эта штука работает.Нужен jQuery.

function myconfirm(kyssa, elm, e){ // neG
    if(jQuery('#confirmquestion').data('result')){
        var V = jQuery('#confirmquestion').data('result');
        jQuery('#confirmquestion').remove(); 
        return V == 'Y' ? true : false;         
    }else if(!jQuery('#confirmquestion').length){
        jQuery('body').append('<div id="confirmquestion">'+
        '<h4>Kinnitus</h4>'+
        '<div id="kyssa">'+kyssa+'</div>'+
        '<center>'+
        '<button onclick="jQuery(\'#confirmquestion\').data(\'result\', \'Y\');">Jah</button>&nbsp;'+
        '<button onclick="jQuery(\'#confirmquestion\').data(\'result\', \'N\');">Ei</button></div>'+
        '</center>');
        jQuery('#confirmquestion button').click(function(){
            jQuery(elm).trigger(e.type);
        })
    }       
    return false;
}

onChange="if(myconfirm(\'Saada kiri: \'+jQuery(this).find(\'option:selected\').html()+\' ?\', this, event)) { ... }"

CSS

#confirmquestion{
    border:1px solid #999;
    background:white;
    padding-bottom: 30px;
    position:fixed;
    width:300px;
    font-size:12px;
    top:45%;
    left:50%;
    margin-left:-150px;
}

#confirmquestion h4 {
    background:blue;
    color:white;
    margin:0;
    padding: 2px 5px;
    border-bottom:#777; 
    text-align:center;
}

#confirmquestion #kyssa {
    padding: 30px 25px;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top