api.modifyClass が時々動作しない

編集:バグとして再分類されました。
完全な再現手順は以下にあります。

テーマコンポーネントでapi.modifyClassを使用しています。

ほとんどのページでは正常に動作しますが、一部のトピックでは、ページがリロードされたときにプロパティがユーザーモデルに追加されません。ほとんどのトピックで機能し、一部のトピックで機能しない理由、または機能しないトピックに共通するものを特定できません。
私がここで何か間違っていることを理解している人はいますか?

TL;DR modifyClassの下にモデルのapi.container.lookupを追加すると、この問題が回避されます。

「いいね!」 1

まさか。わかったかもしれません!

pluginId を追加する必要があると思います

     <script type="text/discourse-plugin" version="0.1">
    api.modifyClass('model:user', {
      pluginId: 'my-plugin',
      testProperty: function() {
        return 1;
      }
    });
</script>

後期のバージョンでは必須です。昨日、これを追加するためにいくつかのテーマにPRを提出しました。ついにプラグイン/テーマ開発者になるかもしれません。

「いいね!」 2

ジェイさん、ありがとうございます!テストインスタンスでは実際に効果がありました。
しかし、残念ながら万能薬というわけではなく、問題はまだ残っています :frowning:

「いいね!」 1

はい、pluginId は、変更が二重に適用されるのを防ぐために存在していると思います。それがないことで、一度も実行されなかったことを説明できるはずがありませんか?

「いいね!」 1

ちぇっ。何か分かったと思ったのに。:crying_cat_face:

他の何かがクラスを変更している場合、どちらがそれを実行するかという競合状態になるのではないかと思いました。しかし、JavaScriptは私にとってはまだほとんど謎です。

「いいね!」 2

コードの問題はまだ残っているので、提起するのはもっともです。

「いいね!」 1

私もそれは考えましたが、これはテーマコンポーネントがこれしかないテストサイトでも失敗します。

「いいね!」 1

ちなみに、これをテーマコンポーネントに次のように追加した場合:

  • /javascripts/discourse/initializers/test-init.js.es6

動作は変わりますか/改善されますか?

これらのものが意味的に同一であるかどうかはわかりません…

…理論的には、ブラウザがリフレッシュされたときに両方とも評価されるはずであり、その後、変更はすでに適用されているはずなので、ルート遷移時の競合状態は無関係になるはずです…

「いいね!」 1

いいえ、動作は同じです。

javascripts/discourse-test/initializers/initialize-discourse-test.js.es6 を使用してテーマコンポーネントを作成しました。

import { withPluginApi } from "discourse/lib/plugin-api";

export default {
  name: 'discourse-test-initializer',
  initialize(){
    console.log('here1');
    withPluginApi("0.1", api => {
      console.log('here2');

      api.modifyClass('model:user', {
        pluginId: 'test',
        testFunction: function() {
          console.log('here3');
          return 2;
        }
      });

    });
  }
}

すべてのページで以下が出力されます。

here1
here2

一部のトピックでは、コンソールで Discourse.currentUser.testFunction() を入力すると機能し、出力として here32 が得られます。

一部のトピックでは機能しません(Uncaught TypeError: Discourse.currentUser.testFunction is not a function)。

「いいね!」 2

通知で、削除されたと思われる役立つ投稿を見ました。
提案は機能しませんでしたが、問題を解決するのに役立つ手がかりが含まれていました。

機能しないコードの下に次のスニペットを追加すると、発生していた問題が一貫して解決されました。これは、安定版とテスト済み両方の複数の独立したフォーラムでテストしました。これは Bug として再分類されるべきだと思います…

<script type="text/discourse-plugin" version="0.1">
const userModel = api.container.lookup("model:user");
</script>

@Johani ご協力ありがとうございました!

「いいね!」 2

バグとして再分類します。

modifyClass が呼び出されるたびにログに記録されるように、プラグイン API コード app/assets/javascripts/discourse/app/lib/plugin-api.jsconsole.log を追加しました。

競合がないことを確認するために、すべての外部プラグインを削除しました。

再現手順:

  • stable で空のフォーラムを作成します(Ember CLI なし)。これは、テスト合格(Ember CLI なし)でも機能しません。Ember CLI ではテストしていません。

  • Common - Head に以下を追加したテーマコンポーネントを追加します。

#1 動作中

<script type="text/discourse-plugin" version="0.1">
    api.modifyClass('model:user', {
      pluginId: 'test-tc',
      testFunction: function() {
        return 1;
      }
    });
</script>
  • ホームページを読み込みます。

  • コンソールに modifyClass called for model:user _application-08d9058ddd37ba80992f770509f4919ad0738a17f14fb85167b1dc1f32f8b56e.js:23490:16 Object { pluginId: "test-tc", testFunction: testFunction() } と表示されます。

  • コンソールで Discourse.currentUser.testFunction() と入力します。

  • 「1」が表示されます。

#2 失敗

  • トピック(例:「Welcome to Discourse」)に移動し、ページを再読み込みします。
  • コンソールに同じ「modifyClass called」ログが表示されます。
  • コンソールで Discourse.currentUser.testFunction() と入力します。
  • Uncaught TypeError: Discourse.currentUser.testFunction is not a function と表示されます。

#3 警告付きで失敗

  • テーマコンポーネントの先頭に 1 行追加して、以下のようになります。
<script type="text/discourse-plugin" version="0.1">
    const userModel = api.container.lookup("model:user");

    api.modifyClass('model:user', {
      pluginId: 'test-tc',
      testFunction: function() {
        return 1;
      }
    });

</script>
  • トピック(例:「Welcome to Discourse」)に移動し、ページを再読み込みします。
  • コンソールに同じ「modifyClass called」ログが表示されます。
  • コンソールに \"model:user\" was already cached in the container. Changes won't be applied. という警告が表示されます。
  • コンソールで Discourse.currentUser.testFunction() と入力します。
  • Uncaught TypeError: Discourse.currentUser.testFunction is not a function と表示されます。

#4 動作中

  • lookup 行をテーマコンポーネントの 末尾 に移動して、以下のようになります。
<script type="text/discourse-plugin" version="0.1">
    api.modifyClass('model:user', {
      pluginId: 'test-tc',
      testFunction: function() {
        return 1;
      }
    });

    const userModel = api.container.lookup("model:user");
</script>
  • トピック(例:「Welcome to Discourse」)に移動し、ページを再読み込みします。
  • コンソールに同じ「modifyClass called」ログが表示されます。
  • コンソールで Discourse.currentUser.testFunction() と入力します。
  • 「1」が表示されます :partying_face:
「いいね!」 4

これを再確認します。

Discourse 2.8以降では、Discourse.User.current().testFunction() を使用すると、ケース #2 は引き続き失敗します。

「いいね!」 1

modifyClass についても問題が発生しています。関連があるかどうかわかりません。: Issues overriding getters in a controller (3.0.0)

この種の状況に対する警告を改善しました。

また、原因と解決方法を説明するドキュメントも作成しました。

これで、このトピックのすべての懸念事項に対処できるはずです。もしそうでなければ、失敗したコードの例を共有していただければ確認します。

「いいね!」 11

このトピックは3日後に自動的に閉じられました。新しい返信はもう許可されていません。