1

ユーザー プロファイル情報を含むフォームを検証しています。ユーザーが指定したユーザー名が既に使用されているかどうかをサーバーで確認したいと考えています。次のような検証方法を定義しました。

$.validator.addMethod(
    'check_username', 
    function(value, element, param) { 
        console.log('starting');
        var name_is_in_use = 0;

        // Start the throbber.
        $('form#user-profile-form input#edit-name').addClass('searching');

        // Hit the server and see if this name is already in use by someone else.
        $.ajax({
            url: '/checkusername/' + value + '/" . $form['#user']->uid . "',
            dataType: 'json',
            data: {},
            async: false,
            success: 
                function(data) {
                        console.log('back from the server');
                        name_is_in_use = data; // unnecessary, but whatever

                        // Kill the throbber
                        $('form#user-profile-form input#edit-name').removeClass('searching');
                    },
        });

        return name_is_in_use;
    },
    'Sorry, but this username is already in use.');

全体として、検証プロセスは機能します。私が問題を抱えているのは、入力フィールドに接続された「ビジー」スロバーを適切に機能させることです.スロバーは、通常の状態からビジー状態に決して変化しません。しかし、実際に起こっていることを誇張するためにサーバーに sleep() 呼び出しを追加した後、私が見ているのは、これらの両方の console.log ステートメントが同時にコンソールに表示されることです-サーバーへの呼び出しの後完了しました。これが、throbber の変更が見られない理由を説明してい.searchingます。クラスは、追加された直後に削除されます。しかし、私が理解していないのは、なぜ私が思っていることが起こっていないのかということです:

  1. ブラウザーでフィールドをクリックして、検証メソッドを起動します。
  2. console.log('starting')コンソールに表示される
  3. スロバーがオンになります。
  4. サーバーが呼び出され、少しスリープし、その値を返す間、一時停止があります。
  5. console.log('back')コンソールに表示される
  6. スロバーがオフになります。

代わりに、私はこれを取得しています (throbber クラスの変更を無視します):

  1. ブラウザーでフィールドをクリックして、検証メソッドを起動します。
  2. サーバーが呼び出され、少しスリープし、その値を返す間、一時停止があります。
  3. console.log('starting')コンソールに表示され、遅延なく、
  4. console.log('back')コンソールに表示される

ステップ 3 と 4 はほぼ同時に行われます。

私はこれについて本当に困惑しています。ハンドラーの実行全体が ajax 呼び出しによって停止しているように見えますが、これはまったく意味がありません。誰でもいくつかの洞察を提供できますか? ありがとう!

4

2 に答える 2

3

それは簡単です。それは、通話でに設定しているためですasyncfalse$.ajax

あなたは同期リクエストを行っています。通常、そのようなことが行われると、Web ブラウザーはサーバーからの応答を待っている間、ハングしているように見える傾向があります。

于 2013-02-26T23:32:33.710 に答える
0

OK、私は機能するだけでなく、比較的原理的に見えるものを手に入れました。他の人の役に立つかもしれないという考えで...

$('form#user-profile-form').validate({
    debug: true,
    rules: {
        name: {
            required: true,
            regexp: /\W/,
            remote: {
                url: '/checkusername',
                type: 'post',
                data: {
                    username: function () { return $('#edit-name').val() },
                    uid: " . $form['#user']->uid . "
                    },
                beforeSend: function (jqXHR, settings) {
                                $('form#user-profile-form input#edit-name').addClass('searching');
                            },
                complete: function (jqXHR, settings) {
                                $('form#user-profile-form input#edit-name').removeClass('searching');
                            },
            }
        }
    },

    messages: {
        name: {
            regexp: '" . USERNAME_VALIDATION_MESSAGE . "',
            remote: 'Sorry, but this username has been claimed by someone else.',
            },
        ...
        },
    errorPlacement: function(error, element) {
        switch (element.attr('name')) {
            case 'name':
                error.insertAfter('.control-group.form-item-name > label');
                $('form#user-profile-form input#edit-name').removeClass('searching');
                break;
             ...

ここで注意すべき点:

  • 重労働はremoteオプションを介して行われます。これは、ドキュメントが言うように、このようなものを対象としています。URL のもう一方の端にあるコードは、ユーザー名が使用可能な場合は JSON 化された 1/true を返し、使用できない場合は 0/false を返します。
  • ハンドラーはbeforeSend、サーバー呼び出しが発生する前に、検証の最初にスロバーをオンにします。
  • ユーザーが競合しない名前を指定した場合、completeハンドラーはスロバーをオフにします。
  • サーバーコールが返され、エラーが報告された場合、removeClassコールダウンerrorPlacementはthrobberをオフにします。
  • username既に使用されているテストと、指定された名前が「単語」であることを確認するための正規表現テストの2 つのルールがあるため、messagesセクションでそれぞれに適切なメッセージを指定する必要があります。

ふぅ。コメントは大歓迎です。助けてくれてありがとう!

于 2013-02-27T02:35:50.543 に答える