詳細画面表示時に値の表示を更新したい

初めて投稿させて頂きます。
タイトルの通りではありますが、レコード詳細画面、レコード編集画面の表示イベントのときに値の表示を更新したいと思っております。
(画面上のみの更新)

具体的には以下のようになります。

Aアプリのレコード詳細画面 or レコード編集画面が表示されたら、Bアプリの特定の項目を取得し、Aアプリの該当の項目に反映させたいです。

以下のように記述していますが、
Aアプリの該当の項目が反映されずに困っております。

(function () {
“use strict”;
kintone.events.on([‘app.record.detail.show’, ‘app.record.edit.show’], function(event) {
// レコードの取得
var rec = event.record;
console.log(rec);
var shopId = rec[‘shopId’]value;
// idが空文字 or undefined 以外
if (shopId) {
// 受注マスタに対してRestAPIで該当の項目を取得する
kintone.api(
‘/k/v1/records’,
‘GET’,
{fields: [
‘goods’
],
app: 100,
query: ‘shopId = "’ + shopId + ‘"’
}, function (res) {
if (res.records.length > 0) {

var goods_1 = 0;
                // 取れるのは100件まで
                for (var i = 0; i < res.records.length; i++) {
                    goods_1 += parseInt(res.records[i]['goods'].value);
                }
                event.record['hoge'].value = goods_1;

// 表示されてる
console.log(event.record[‘hoge’].value);
}
return event;
});
}
});
})();

ご指摘頂ければ幸いです。
宜しくお願い致します。

https://cybozudev.zendesk.com/hc/communities/public/questions/202311534-%E8%A9%B3%E7%B4%B0%E7%94%BB%E9%9D%A2%E8%A1%A8%E7%A4%BA%E6%99%82%E3%81%AE%E9%A0%85%E7%9B%AE%E6%9B%B4%E6%96%B0%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6

上記の回答から察するに、レコード詳細画面では私の処理では出来ず、
やるんであれば、RestAPIで該当レコードの更新しないとダメそうですね。。。

鈴木佑介さん、こんにちは。

この辺(1, 2)の内容はご確認頂いているようで、ご認識の通りだと思います。恐らく実現されたいのはこの2つの合わせ技だと思いますが、「レコード追加・編集イベント」と「レコード表示イベント」では、フィールド(レコード)の更新もしくは値の反映方法が異なりますので、kintone.api()のコールバックの中身をイベントタイプによって、 kintone.app.record.set() (レコード追加・編集)と、REST APIによる更新(レコード表示イベント) を使い分けると良いと思います。

Ryu Yamashita さん
ご回答ありがとうございます。

イマイチまだよくわかっていないのですが、
レコード編集イベントの場合は、
kintone.events.on(app.record.edit.show, function(event) {
// 処理を書く
});

となるかと思いますが、
その場合に、ご教授頂いた、kintone.app.record.set()は行えませんよね?
注意事項の
kintone.events.on のインベントハンドラ内で kintone.app.record.set および kintone.mobile.app.record.set を実行することはできません。 上記のイベントハンドラ内ではレコードデータの取得は引数のeventオブジェクトを、レコードデータの更新はeventオブジェクトのreturnを使用してください。

と書いてあるので、出来ないと思ってます。

レコードの表示イベント時には最初に書いた処理に
レコード更新のRESTAPIを呼び出すというご教授頂いた方法に関しては納得しております。

ご指導頂ければ幸いです。

レコードの詳細画面表示時には、
以下のようなコードにしてみました。

(function () {
“use strict”;
kintone.events.on([‘app.record.detail.show’], function(event) {
// レコードの取得
var rec = event.record;
console.log(rec);
var shopId = rec[‘shopId’].value;
// 店舗IDが空文字 or undefined 以外
if (shopId) {
console.log(shopId);
// RestAPIで該当の項目を取得する
kintone.api(
‘/k/v1/records’,
‘GET’,
{fields: [
‘goods’
],
app: 100,
query: ‘ShopId = "’ + shopId + ‘"’
}, function (res) {
var putRecords;
var goods_1 = 0;
for (var i = 0; i < res.records.length; i++) {
var record = res.records[i];
goods_1+= parseInt(record[‘goods’].value);
}
putRecords = {
app : kintone.app.getId(),
id : kintone.app.record.getId(),
record : {
A_APP_Goods : {
value : goods_1
}
}
}
kintone.api(kintone.api.url(‘/k/v1/record’, true), ‘PUT’, putRecords, function(resp) {
console.log(resp);
});
}
);
}
return event;
});
})();

上記で更新されて画面に表示されるようになりましたが、
詳細画面に表示後、更新しようとすると、

-レコードを再読み込みしてください。編集中に、ほかのユーザーがレコードが更新されました。
(GAIA_UN03 1505999166-1138393464)
と表示されるようになってしまいました。

レコード更新時の処理はまだ何も書いておりません。(一旦消したので。)

ご教授頂ければ幸いです。

上記で更新されて画面に表示されるようになりましたが、
詳細画面に表示後、更新しようとすると、

-レコードを再読み込みしてください。編集中に、ほかのユーザーがレコードが更新されました。
(GAIA_UN03 1505999166-1138393464)
と表示されるようになってしまいました。

上記のように記述しましたが、
詳細画面→更新ボタン押下→更新画面→適当な入力→保存
では上記の事象になりますが、
詳細画面→更新ボタン押下→更新画面→F5押下→適当な入力→保存
であれば、保存できることは確認しました。

理由がよくわかりませんが。。。

詳細画面→更新ボタン押下→更新画面→適当な入力→保存
では上記の事象になりますが、
詳細画面→更新ボタン押下→更新画面→F5押下→適当な入力→保存
であれば、保存できることは確認しました。

上のコードを見る限りはレコード詳細画面表示時に発火しそうですが、自作のボタン等を設置されている感じでしょうか。

また、再読込を促すメッセージは他に(自分を含めて)編集画面を開いて更新した時が基本になりますが、レコードの更新履歴はどのようになってますでしょうか?

また、

注意事項のkintone.events.on のインベントハンドラ内で kintone.app.record.set および kintone.mobile.app.record.set を実行することはできません。 上記のイベントハンドラ内ではレコードデータの取得は引数のeventオブジェクトを、レコードデータの更新はeventオブジェクトのreturnを使用してください。

こちらの話は先ほどの(2)の中で議論されています。

target_value を編集画面表示時にセットしようとすると、基本は次のようになります。

kintone.events.on(['app.record.edit.show'], function(event) {
  event.record['target_field']['value'] = target_value;
  return event; // ← ここでセットしている
});

この場合には、return event のところでセットしています。

しかし、kintone.api() や自作ボタンクリック等のイベントののコールバックの中ではkintone.events.onに、return eventで返すことができなくなります。その時に使うのが、kintone.app.record.getId()/set() となります。

(function () {
  "use strict";
  kintone.events.on(['app.record.edit.show'], function(event) {
    // レコードの取得
    var rec = event.record;

    var shopId = rec['shopId']value;
    // idが空文字 or undefined 以外
    if (shopId) {
      // 受注マスタに対してRestAPIで該当の項目を取得する
      kintone.api(
        '/k/v1/records',
        'GET',
        {fields: [
          'goods'
        ],
        app: 100,
        query: 'shopId = "' + shopId + '"'
      }, function (res) {
        if (res.records.length > 0) {
          var goods_1 = 0;
          // 取れるのは100件まで
          for (var i = 0; i < res.records.length; i++) {
            goods_1 += parseInt(res.records[i]['goods'].value);
          }
          event.record['hoge'].value = goods_1;
          // 表示されてる
          console.log(event.record['hoge'].value);
        }
        //return event; // ← これは、先ほどのルールで kintone.events.on にしか返せない
        // kintone.api()のコールバック中なので kintone.app.record.get()/set() で値をセットする
        var record = kintone.app.record.get();
        record['record']['target_field']['value'] = target_value;
        kintone.app.record.set(record);
      });
    }
  });
})();

こちらでも、類似の手法が使われていますので、参考になるのではないかと思います。

Ryu Yamashita さん
返信遅くなり恐縮です。

ご回答ありがとうございます。
レコード編集画面でのサンプルコード提示とご説明ありがとうございます。
kintone.app.record.set()、get()の使い方と公式の注意事項の意味がわかりました。
ありがとうございます。

上のコードを見る限りはレコード詳細画面表示時に発火しそうですが、自作のボタン等を設置されている感じでしょうか。
また、再読込を促すメッセージは他に(自分を含めて)編集画面を開いて更新した時が基本になりますが、レコードの更新履歴はどのようになってますでしょうか?

との事ですが、
Aアプリのレコード詳細画面表示時に、Bアプリからデータの取得を行い、Aアプリのレコードを更新しています。
その為、レコードの更新履歴は詳細画面を表示したタイミングで更新されます。

ここまで聞いといて本末転倒ではありますが、
https://cybozudev.zendesk.com/hc/communities/public/questions/201329284-kintone%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6?locale=ja

上記のような方法がいいのでしょうか?
考えていた設計では、
Aアプリで詳細画面もしくは編集画面が表示された際にBアプリの特定の項目をRESTAPIで取得し、Aアプリに設定しようと思っておりましたが、
Bアプリで特定の項目が更新された際にRESTAPIでAアプリの特定の項目を更新するといった方法です。

確かに上記であれば、Aアプリでリロードもせずに済むので、不要な実装も避けられる気がしますが、悩んでます。

ご指摘頂ければ幸いです。
宜しくお願い致します。

確かに上記であれば、Aアプリでリロードもせずに済むので、不要な実装も

ぱっと見ですが、リンク先でやっていることと基本的に相違はないのかなぁと思います。エラーの原因はちょっと想定が追いつかないところです。

リロードに関しましては、個人的にはリンク先で斎藤さんも言及されていますが、変化をピックアップしてリロードしてあげた方がユーザーにはわかりやすいかなぁという気はします。

Bアプリで特定の項目が更新された際にRESTAPIでAアプリの特定の項目を更新するといった方法です。

こちらのコメントを含めたところでですが、どちらのアプリが更新頻度が高いかの考慮が必要そうです。同時更新の危険が低い方でPUT処理するようにするのが良いと思います。

Ryu Yamashita さん
ご回答ありがとうございます。

リロードに関しては、リンク先の斉藤さんの意見をもとに条件分岐を追加し、リロードがループするという事はなくなりました。
※勘違いして、kintone.app.record.get()しなければいけないところをevent.recordで取得したものと比較していたので、条件に当てはまらずハマってました。。。

とりあえず、編集画面表示時と詳細画面表示時には入れたい処理がとりあえずは入れることが出来ました。
ご指摘、ご助言ありがとうございます。

また、別件ではあるのですが、
編集画面表示のイベント時に以下のようなコードで値を設定しています。
var setRecord = kintone.app.record.get();
var goods_1 = 1/3;
setRecord[‘record’][‘goods’][‘value’] = goods_1;

上記は実際の実装とは異なりますが、取得した項目の平均値を出すような実装がありまして、それの例になります。
上記の実装を行った場合に設定する項目が数値項目であり、且つ小数第3桁までしか受け付けない設定にしておりますが、関係なく小数点が12ケタで最後に丸められて設定されてしまいます。

これはkintoneの仕様なんでしょうか?
もしそうであれば、実装で少数点第3位以下を切り捨てる処理などを入れないと思っており、質問させて頂きました。

もし、ご存じでしたら
ご教授頂ければ幸いです。
宜しくお願い致します。

上記の実装を行った場合に設定する項目が数値項目であり、且つ小数第3桁までしか受け付けない設定にしておりますが、関係なく小数点が12ケタで最後に丸められて設定されてしまいます。
これはkintoneの仕様なんでしょうか?

細かい設定はしたことありませんが、「高度な設定(https://subdomain.cybozu.com/k/admin/app/info?app=appId)」のところで、所謂有効桁数と丸め方が設定可能で、そちらは小数部4桁がデフォルトだったと思います。こちらの制御が効いてないようなイメージでしょうか。