1

関数はリモートの場所からコンテンツをフェッチするため、非同期コールバックを設定する必要があります。私はこれをやっています:

$.when( priv[box.view.renderWith](content, box.view.gadget_id) ).then(function(late) {
    console.log("done");
    console.log(late)
    console.log($(content))
    $(content).append(late).enhanceWithin();
});

私のwhen関数は単一の Ajax リクエストをトリガーします。そのコールバックでは、追加する要素を返しています$(content)

私の問題は、then私のajaxコールバックが実行されて何かを返す前に、関数がすぐに起動することです。

質問: ajax-request を行う関数では
使用できませんか? when()で直接 ajax リクエストを行う必要がありwhen()ますか? または、なぜthen()すぐにトリガーされるのですか? どうすればこれを回避できますか?

ありがとう!

編集: スニペットの現在のバージョン:

$.when( priv[box.view.renderWith](content, box.view.gadget_id) ).then(function(fragment) {
    // DOM manip...
    console.log("NOW WE ARE DONE WITH WHEN");
    console.log(fragment)
    $(content).append(fragment).enhanceWithin();
});

そして、私が呼び出している関数(コンテンツ生成部分なし):

priv.constructListbox = function (element, internal) {
  var no_data_body,
    no_data_cell,
    portable,
    gadget_id = element.getAttribute("data-gadget-id") || internal,
   settings = priv.gadget_properties[gadget_id],
    portal_type = settings.portal_type_title,
    // wrapper
    $parent = $(element.parentNode);

  if (settings !== undefined) {

   // ASYNC > this will trigger an Ajax request
    portable = priv.erp5.allDocs({
      "query": "type: \"" + settings.datasource + "\"",
      "limit": [0, (settings.configuration.pagination.items_per_page_select[0] || 30)],
      "wildcard_character": "%",
      "include_docs": true
    }).always(function (answer) {

      .... stuff ...

      // finish
      // return to calling function
      if (internal) {
        console.log("foo");
        console.log("no we only give back a fragment");
        return fragment_container;
      }
      $parent.empty().append( fragment_container ).enhanceWithin();
    });

    // if internal call, return the promise object
    if (internal) {
      console.log("foo internal, promise");
      return portable;
    }
  } else {
    // error handler
   }
};

コールバックportable内でコンソールを実行すると、オブジェクトが取得されるため、関数は promise と要素を返します。しかし、解決したとき、私は何も得ていないときに私が得られることを望んでいました:-(thenpromisefragment_container

うまくいけば、十分に明確です。

4

1 に答える 1

1

私がこれまでに聞いた最善のアドバイスは、Async プログラミングを通常の関数のように扱い、最後に promise を追加することです。

fragment_container を設定している場所がわかりにくいのですが、ここに行きます..

priv.constructListbox = function (element, internal) {
   var dfd = new $.Deferred();

   ...

   if (settings !== undefined) {

     portable = priv.erp5.allDocs({
       "query": "type: \"" + settings.datasource + "\"",
       "limit": [0, (settings.configuration.pagination.items_per_page_select[0] || 30)],
       "wildcard_character": "%",
       "include_docs": true
     }).always(function (answer) {

  .... stuff ...

       // finish
       // return to calling function
       if (internal) {
         console.log("foo");
         console.log("no we only give back a fragment");
         dfd.resolve({message:"You did it!", element: fragment_container });
       }
       $parent.empty().append( fragment_container ).enhanceWithin();
     });
   } else {
     dfd.reject({result:"Nope - no data came out"});
    // error handler
   }
   return dfd.promise();
}; 

次に、返されたものを簡単に確認できます。

$.when( priv[box.view.renderWith](content, box.view.gadget_id) ).then(function(fragment) {
    console.log("NOW WE ARE DONE WITH WHEN");
    console.log(fragment);
},
function(fragment) {
    console.log("It failed");
    console.log(fragment);
});
于 2013-09-12T14:29:32.383 に答える