22

デフォルトのアラートの代わりに、 http: //abeautifulsite.net/notebook/87 の jQuery アラート ダイアログ ライブラリを使用しようとしています (これは私の意見ではかなりひどいものです)。これは素晴らしいライブラリのようですが、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ボタンからの呼び出し:

プラグインの Web サイトにコメントを投稿し (今朝)、Google で javascript を検索し、コールバックが結果なしで完了するのを待っていました。

残りのJavaScriptが実行される前に、コールバックを正しく使用して結果を取得する方法についてのアイデアはありますか?

ありがとう。

4

9 に答える 9

19

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');
})
于 2009-01-12T22:10:30.103 に答える
16
jConfirm('are you sure?', 'Confirmation Dialog',
    function(r) {
        result = r;
        response = true;
        return r;
    }
);
if (response == true) {

これは、非同期コードを使用して発生する一連のイベントを誤解していることを示しています。インラインで記述したからといって、厳密に上から下に実行されるわけではありません。

  1. jConfirm が呼び出され、関数をパラメーターの 1 つとして受け取ります。これは記憶されています。
  2. jConfirm はその UI をページに表示し、すぐに戻ります。
  3. 「if (response==true)」行が実行されます。実際には、これは「if (response)」と読むだけでよく、ブール値の比較は不要です。しかし、いずれにせよ、応答はもちろん false です。関数はあきらめて終了し、制御をブラウザーに戻します。
  4. ユーザーが jConfirm の UI をクリックします。
  5. jConfirm は、アクションにジャンプして、以前に記憶されていた関数をコールバックするようになりました。
  6. ネストされた関数は応答を true に設定します。「if (response==true)」条件で何かを行うには遅すぎます。

代わりに「//wait for response」と書きましたが、実際にそれを行う JavaScript コードは記述できません。ブラウザが jConfirm UI でクリック イベントを発生させて処理を続行させる前に、関数が戻ってブラウザに制御を戻す必要があります。

非同期コードを同期コンテキストで動作させる (およびその逆) 方法が存在します。特に、スレッドとコルーチン (およびそれらの限定された関係ジェネレーター) です。ただし、JavaScript にはこれらの機能がまったくないため、ライブラリが使用している同期または非同期モデルに適合するようにコードを記述する必要があります。

于 2009-01-12T21:41:30.177 に答える
8

コールバックは非同期であるため (少なくとも、ユーザーが何かをするのを待っているという意味では)、コールバック内で必要なことを処理する方が簡単かもしれません。

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

@klogan [コメント]

ここからこれらを入手したと思いますか?

ページに答えが表示されます: ( Usageの下を見てください)

これらのメソッドは、confirm() および prompt() と同じ値を返しません。コールバック関数を使用して、結果の値にアクセスする必要があります。(詳細については、デモを参照してください。)


@クローガン

私が言いたいのは、あなたが望むことを達成するための簡単な方法は本当にないということです. 手続き型プログラミングとイベント駆動型プログラミングを相互に関連付けようとしていますが、これは 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;
}

于 2009-01-12T19:36:57.450 に答える
5

技術的にはそうですが、ウェブサイトではそうしません。

Narcissusに基づいたNarrative JavaScriptを見てみましょう。

Narrative JavaScript は、非同期イベント コールバックのブロック機能を有効にする JavaScript 言語の小さな拡張機能です。これにより、非同期コードがさわやかに読みやすく、理解しやすくなります。

Seleniumはこの技術を使用しています。


アップデート

JavaScriptストランドをチェックしてください:

JavaScript Strands は、JavaScript 言語にコルーチンと協調スレッドのサポートを追加して、非同期イベント コールバックのブロック機能を有効にします。これにより、非同期操作を利用するコードがより直線的になり、読みやすく、管理しやすくなります。Strands は Neil Mix によって書かれた Narrative JavaScript に基づいて構築されており、Narrative JavaScript の多くは、このドキュメントの多くを含めて Strands に残されています。

JavaScript では、イベントが発生するまでコードを単純に待つことはできません。イベントは、常に別の非同期イベント ハンドラーによって処理される必要があります。これで問題ない場合もありますが、多くの場合、単純な一連のステートメントであるはずのものが、ひどくゆがんでしまいます。また、呼び出し関数はコールバック ハンドラーを提供することを認識している必要があるため、機能をカプセル化する機能が壊れます。Strands は、実行のスレッドを一時停止および再開する機能を提供します。イベントが終了すると、実行は再開を一時停止できます。これにより、実装をカプセル化する単純で直線的で読みやすいコードで、読みにくい非同期イベント処理を記述できます。

于 2009-01-12T19:50:07.470 に答える
0

この問題の可能な解決策を思いついたと思います。私はこの記事を読んでいました: http://treasure4developer.wordpress.com/2008/06/23/calling-postback-event-from-javascript/

基本的には、javascript からのポストバックを強制するという考え方です。最初は、ポストバックは機能するが、ボタン イベントを呼び出さないことがわかりましたが、記事を読んだ後、それが javascript ポストバックであるかどうかを検出し、単に呼び出すことができることがわかりました。処理を行う方法

よろしく DotnetShadow

于 2009-01-14T05:48:51.240 に答える
0

これは機能します。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;
}
于 2012-01-10T10:11:12.337 に答える
0

コールバックをメッセージの送信と考えると、コードの構造が改善されます。

于 2012-03-08T04:11:49.857 に答える
0

I would assume you'd have to grab the response like this. I don't think you need a callback.

function confirm() {
        var response = jConfirm('are you sure?', 'Confirmation Dialog');
        if (response) {
            alert(result);
        }
        else {
            //wait for response
            alert('hi');
        }
    }
于 2009-01-12T19:19:31.680 に答える
0

男たちが言ったように、方法はありません!しかし... 私たちの国(ブラジル)では、ル・ガンビと言うのが常です:

次のようなことができます。

<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}"/>

そしてJavaScript:

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 を使用しています。

さようなら、これが誰かに役立つことを願っています。

于 2011-10-11T18:15:51.387 に答える