0

Magento がカテゴリを処理する方法を変更して、カートに追加する URL の ajax リクエストを連鎖させることで、ユーザーがカテゴリ ページから複数の構成可能な製品を一度に追加できるようにしました。

基本的に、ユーザーが追加したいアイテムのチェックボックスを選択すると<li>、製品が「アクティブ」のクラスになります。この jQuery<li>は、アクティブなクラスを持つそれぞれを取得し、変数 theLink で選択されたドロップダウンから「カートに追加する URL」を取得します。

$j('li.active').each(function(){
            var theLink = $j(this).find('.shopthislookpageselect').val();
            var successString = "was added to your shopping cart."
            $j.ajax({
                beforeSend: function(){$j('#modalBackground').show();},
                type:"POST",
                url: theLink,
                success: function(data){
                    var returnPage = data;
                    var exists = (returnPage.indexOf(successString) !== -1);
                    if (exists) {$j('.col-main').prepend('<ul class="messages"><li class="success-msg"><ul><li><span>The items selected were added to your shopping cart. View your cart <a href="https://www.culturekings.com.au/checkout/cart/">HERE</a></span></li></ul></li></ul>'); $j("html, body").animate({ scrollTop: 0 }, "slow"); }
                    else {alert ('There was a problem adding these products to your cart. \n Please select the View Full Product Info link to add these items individually.')}
                    },
                error: function(){alert('There was a problem adding these products to your cart. \n Please select the View Full Product Info link to add these items individually.');},
                complete: function(){$j('#modalBackground').fadeOut(200);}
            });
});

divmodalBackgroundは透明な全幅と高さのオーバーレイで、各 ajax 呼び出しの開始時に表示され、最後に非表示になるローディング gif があります。

問題は、modalBackground が最初の ajax 呼び出しの開始時に表示され、最後に非表示になりますが、その後の他の呼び出しでは再び表示されないことです。成功関数の呼び出しが成功するたびに最後に表示される成功メッセージを数えることができるため、この関数がまだ実行されていることがわかります。

beforeSend は 1 回だけ起動しますか? もしそうなら、なぜですか?または、オーバーレイに対してこれを別の方法で処理する必要があります。

Magneto のカートに追加するコントローラーで大きな変更を加えないと、すべての製品を一度に追加することはできないので、これらの複数の Ajax リクエストを実行するのに行き詰まっていることに注意してください。

4

2 に答える 2

3

アプローチは次のとおりです。

// this will store the ajax requests with are jQuery.Deferred()
var promises = [];

// ajaxSettings.beforeSend is actually better to use to modify the xhr.
// You can just do this beforehand.
$j('#modalBackground').show();
$j('li.active').each(function(){
   // all your other stuff
   // success and error callbacks will still run for each one.
   promises.push($j.ajax({
       type:"POST",
       url: theLink,
       success: function(data){
           var returnPage = data;
           var exists = (returnPage.indexOf(successString) !== -1);
           if (exists) {$j('.col-main').prepend('<ul class="messages"><li class="success-msg"><ul><li><span>The items selected were added to your shopping cart. View your cart <a href="https://www.culturekings.com.au/checkout/cart/">HERE</a></span></li></ul></li></ul>'); $j("html, body").animate({ scrollTop: 0 }, "slow"); }
           else {alert ('There was a problem adding these products to your cart. \n Please select the View Full Product Info link to add these items individually.')}
       },
       error: function(){alert('There was a problem adding these products to your cart. \n Please select the View Full Product Info link to add these items individually.');}
    }));
});

// What this does is gathers all those jQuery.Deferred and when
// all of them are done, runs the done callback.
$j.when.apply($, promises).done(function() {
    $j('#modalBackground').fadeOut(200);
});

それはすべて同じ関数で発生するため、どのように呼び出しても、すべて一緒に実行してください。

Deferred() の詳細については、http: //api.jquery.com/category/deferred-object/をご覧ください。

于 2013-07-04T06:19:18.863 に答える
0

この操作の非同期性に関連するタイミングの問題を扱っているようです。$j('#modalBackground').show(); を起動することをお勧めします。1 回だけコマンドを実行し、1 回だけフェードします。したがって、本質的には、次のようなことをしたいと思うでしょう:

$j('li.active').each(function(index){
            if(index===0) {
                $j('#modalBackground').show();
            }
            var theLink = $j(this).find('.shopthislookpageselect').val();
            var successString = "was added to your shopping cart."
            $j.ajax({
                type:"POST",
                url: theLink,
                success: function(data){
                    var returnPage = data;
                    var exists = (returnPage.indexOf(successString) !== -1);
                    if (exists) {$j('.col-main').prepend('<ul class="messages"><li class="success-msg"><ul><li><span>The items selected were added to your shopping cart. View your cart <a href="https://www.culturekings.com.au/checkout/cart/">HERE</a></span></li></ul></li></ul>'); $j("html, body").animate({ scrollTop: 0 }, "slow"); }
                    else {alert ('There was a problem adding these products to your cart. \n Please select the View Full Product Info link to add these items individually.')}
                    },
                error: function(){alert('There was a problem adding these products to your cart. \n Please select the View Full Product Info link to add these items individually.');},
                complete: function(){
                    if(index===($j('li.active').length-1)) {
                        $j('#modalBackground').fadeOut(200);
                    }
                }
            });
});

このコードは、不要な表示と非表示が互いに競合するのを防ぎます。これが当面の問題だと思います。

beforeSend は完了イベントの直後に起動するのに対し、完了イベントは応答の遅延に基づいて任意の起動時間を持つことに注意してください。

于 2013-07-04T06:21:38.793 に答える