テンプレートでテキストを条件付きでレンダリングする適切な方法--または1回のレンダリングでVALUEを2回変更する

プラグインがあり、それを使って(ほぼ)Digital Ocean の Droplet を作成し、Discourse をインストールしています。

Rails モデル、作成される Droplet、そしてその Droplet にインストールされる Discourse インスタンスに関する情報をレンダリングするテンプレートを持つページもあります。Rails と Ember の間で必要な情報が MessageBus を介して流れるように設定はできています。以下のような状況に応じて、表示する内容を切り替えたいと考えています。

  • Droplet 作成に必要な情報が揃っているか
  • Droplet 作成タスクが実行中か(これがモデル内の情報を更新します)
  • Discourse がインストール済みか

しかし、以下のようなエラーが頻繁に発生します。

   You modified "hasStatus" twice on <@ember/component:ember660> in a single render.

編集:これは、同じものを監視する computed 関数が 2 つあったことが原因でした。

ようやく気づいたのですが、{{#if hasStatus}}(これは computed 関数です)のようなものをテンプレート内で使うことはできません。なぜなら、「Droplet 作成」ボタンがクリックされた後にステータスを表示するにはページを再レンダリングする必要があるからです(その際、インストールの進行状況を表示する installation_status 変数が設定されます)。

あるいは、何か別のエラーがトリガーになっている可能性があり、今のやり方で問題ないのでしょうか?

つまり、必要なことは <gasp> CSS を使って各要素を隠すことでしょうか?

「いいね!」 1

さて、このような投稿をする際によくあることですが、答えは私が想像していたよりもさらに奇妙です。

{{#if server.value}} のようなものを使用し、MessageBus によって value がプッシュされる場合、Rails コンソールから更新を行えば期待通りに動作します。nil または nil 以外に設定すると、ページの該当部分が期待通りに表示・非表示になります。ターミナルから Ansible タスクを実行すると、Ansible がルート経由で新しい値をプッシュし、レコードが更新され、それがメッセージバスにプッシュされるため、テンプレートの該当部分が期待通りに表示されます。

しかし、Ansible が Discourse のジョブによって実行される場合、Rails がメッセージバスにデータをプッシュしていることは確認できます。また、ブラウザの JavaScript コンソールでは、その値を追跡する計算関数が発火していることが確認でき、値は null となっています。ブラウザをリロードするとデータが存在し、ページは期待通りにレンダリングされます。これは開発環境特有の曖昧さであり、本番環境では異なるかもしれません。

もしかしたら、これが関係しているのでしょうか?

さて、そのエラーについてはまだ心配していますが、アクションに以下を追加しました。

window.location.reload(true);

ページがリロードされ、その後すべてが正常に動作しているようです。

「いいね!」 1