スピナ―表示について

久保と申します。
スピナ―表示について質問させていただきます。

Aアプリに各種明細情報が複数件登録されています。
BアプリでAアプリの特定のレコードを集計し表示・登録します。
現在、Aアプリのレコードが多くBアプリのフォームを開くときに時間がかかってしまっています。
「spin.js を使って、スピナー(ローディングアイコン)を設定しよう!」を参考に集計処理中にスピナ―を表示させようとレコードの追加・編集イベントで showSpinner() をコーディングしてみましたが、現状スピナ―は表示されません。
レコードの追加・編集イベントのreturn eventする前だからでしょうか?
どの様にコーディングすればスピナ―を表示できますでしょうか?

初歩的な事で申し訳ありません。よろしくお願いします。

kuboさん

バックのレイヤーが上手くしかれないケースがあるようですので、showSpinner()の関数を次のように書き換えてみてください。関数が呼べる状態で、処理の返し前にshowSpinner()、コールバック内等の処理が終了する箇所にhideSpinner()を入れれば大丈夫だと思います(ちなみに、この動作はretrun eventには特に関係のないプロセスです)。

function showSpinner() {
    // 要素作成等初期化処理
    if ($('.kintone-spinner').length == 0) {
      // スピナー設置用要素と背景要素の作成
      var spin_div = $('<div id ="kintone-spin" class="kintone-spinner"></div>');
      var spin_bg_div = $('<div id ="kintone-spin-bg" class="kintone-spinner"></div>');
      // スピナー用要素をbodyにappend
      $(document.body).append(spin_div, spin_bg_div);
      // スピナー動作に伴うスタイル設定
      $(spin_div).css({
        'position': 'fixed',
        'top': '50%',
        'left': '50%',
        'z-index': '510',
        'background-color': '#fff',
        'padding': '26px',
        '-moz-border-radius': '4px',
        '-webkit-border-radius': '4px',
        'border-radius': '4px'
      });
      $(spin_bg_div).css({
        'position': 'absolute',
        'top': '0px',
        'z-index': '500',
        'width': '100%',
        'height': '200%',
        'background-color': '#000',
        'opacity': '0.5',
        'filter': 'alpha(opacity=50)',
        '-ms-filter': "alpha(opacity=50)"
      });
      // スピナーに対するオプション設定
      var opts = {
        'color': '#000'
      };
      // スピナーを作動
      new Spinner(opts).spin(document.getElementById('kintone-spin'));
    }
    // スピナー始動(表示)
    $('.kintone-spinner').show();
  }

早速の回答ありがとうございます。
なにせJavascript初心者でコールバックの記述がよく判っていません。。。
ネットで調べてもみましたが、なかなか理解できません。
具体的にどの様に記述すればよいか教えて頂けますでしょうか?
教えて頂いたshowSpinner()だけをレコード追加・編集イベントに記述するとスピナ―は表示されるのは確認しました。

// レコード編集、追加時の処理
kintone.events.on([‘app.record.edit.show’, ‘app.record.create.show’], function (event) {
var record = event.record;
// スピナー表示
showSpinner();
// 別アプリの明細集計
SetScreenData(event);
// スピナー非表示
hideSpinner();
return event;
});

こんな単純な記述でないのは判るのですが。
申し訳ありませんが、よろしくお願いします。

非同期処理とコールバックについてはここでも度々トピックにあがっていますので、そちらも参考にしてください。

例えば、kintoneのJavaScriptの関数も殆ど非同期処理(Promiseはありますが)ですが、見た目には関数の引数に関数が入っているものと言いますか。その引数になっている関数内の処理をコールバックといいます。

var rec_id;
    kintone.api(kintone.api.url('/k/v1/records', true), 'GET', {
      app: kintone.app.getId()
    }, function(resp) {
      // (1)レコード番号を表示する(コールバック内)
      rec_id = resp['records'][0]['$id']['value'];
      alert(rec_id);
    }, function(resp) {
      // エラーの場合はメッセージを表示する
      var errmsg = 'レコード取得時にエラーが発生しました。';
      // レスポンスにエラーメッセージが含まれる場合はメッセージを表示する
      if (resp.message !== undefined){
        errmsg += resp.message;
      }
      alert(errmsg);
    });

    // (2)レコード番号を表示する(コールバック外)
    alert(rec_id);

コールバック内であればその非同期処理(上の例はレコード取得)のプロセス実行後に実行されるので、その結果を用いた処理が(1)のように可能です。他方(2)のようにコールバックの外に記述してしまうと、kintone.api()を実行して、次にalert()を実行するというだけで、kintone.api()のプロセス終了を待つわけではないので、たまたまkintone.api()のプロセスがalert()の前に終わっていれば、表示できますし、終わっていなければalert()では、値を得ていないのでundefinedと表示されることになります。

ここで本質ですが、問題とされているのは、スピナーの表示/非表示だと思いますが、現状の問題はスピナーは表示されたが、期待したタイミングでhideSpinner()が効かず非表示にならないという感じでしょうか?

ということであれば、SetScreenData(event)内のエラー等でhideSpinner()の実行に至っていない等の理由が考えられますが、コンソールにエラー等は出ていませんか?

回答ありがとうございます。
いろいろ確認してみました。
やはり非同期処理でshowSpinner()後にSetScreenData(event)を処理していますが、先にhideSpinner()処理が処理されて見た目にスピナー表示されていないような状況でした。
ご指摘のようにプロセス実行順を制御すれば実現できそうです。
コールバックについて、勉強してトライしてみます。
ありがとうございました。

私も問題点を予想し間違えていましたが、・・・

状況からSetScreenData(event)の中にkintone.api()等の非同期処理が入っていると思いますので、その中の処理が終わる箇所でhideSpinner()を記述すれば意図した動きとなると思います。

ご健闘を祈ります。

教えて頂いた非同期処理の終わりにhideSpinner()を行うことで、実現したい動きになりました。
ありがとうございました!

解決されたようで良かったです!

このトピックはベストアンサーに選ばれた返信から 3 日が経過したので自動的にクローズされました。新たに返信することはできません。