3

現在の状況: コンポーネントの「didInsertElement」メソッド内から特定のモデルのレコードを作成し、そのデータをデータ ストアに追加する方法を見つけようとしています。

現在の状況の理由:コンポーネント HBS ファイルのボタンにイベント リスナーをアタッチしています。ボタンの 1 つは、2 つのカスケードされた軽い ajax 呼び出しをトリガーします。これらの ajax 呼び出しの最後の応答によって、レコードを作成する必要があるかどうかが決まります。

私が抱えている問題:コンポーネントから次のようにストアにアクセスしようとすると:

var myStore = this.store

未定義のオブジェクトを取得しています。お尋ねの方のために、私はすでに次の行を私のコンポーネントに追加しています:

store: Ember.inject.service()

そして、私はすでに Ember-Data をインストールしています。

解決策:多くの調査の結果、ストアとのやり取りはメイン ルートを介して行うのが最適であることがわかりました。しかし、ルートからイベント リスナーをコンポーネントの jquery ウィジェットにアタッチするにはどうすればよいでしょうか。

すべてのイベント リスナー コードをコンポーネントからルートに移動し、それによって ember が提供するはずのモジュール性を元に戻す必要のないソリューションはありますか?

4

1 に答える 1

7

this.storeプロパティは、デフォルトで注入された要素 (コントローラーとルート) に存在し、Ember の重要な部分であるゲッターをスキップするため、おそらく使用しないでください。

コンポーネントでそれにアクセスする適切な方法(注入したと仮定)は、次のとおりです。

this.get('store')

多くの調査から、ストアとのやり取りはメイン ルートを介して行うのが最適であることがわかりました。

おそらく (少なくともほとんどの場合) メイン ルートではなく、コンポーネントが存在するコントローラーでストア データにアクセスし、そのデータをコンポーネントに渡すことをお勧めします。

これにはいくつかの理由があります。

  • ルートの主な用途は、データを取得し、アプリのルーティング メカニズム、ユーザーの遷移先、遷移が発生するポイント、および理由などを制御することです。ルートは、どのデータがどのように表示されるか、どのように/いつ表示されるかを制御するべきではありませんその取得。
  • コントローラーの主な用途は、データのマッサージ、準備、変換などです。これには、データのフィルタリング、並べ替え、サブセットの抽出などが含まれます。
  • コントローラー データはテンプレートで直接利用できますが、ルート データは利用できません。

Ember.RouteのsetupController()フックは、実際にはデフォルトでこれを行います。

これは、フックで行われるデフォルトの操作です。setupController()

set(controller, 'model', model);

したがって、コントローラーはデフォルトでモデルにアクセスでき、それをコンポーネントに渡すことができます。

このようにして、データを抽出/取得/処理するロジックを表示するロジックから明確に分離します。

コンポーネント HBS ファイルのボタンにイベント リスナーをアタッチしています。ボタンの 1 つは、2 つのカスケードされた軽い ajax 呼び出しをトリガーします。これらの ajax 呼び出しの最後の応答によって、レコードを作成する必要があるかどうかが決まります。

Ember でこれを行う自然な方法は、ボタンにアクションをアタッチすることです。これはコントローラーに伝播するだけです。

// inside components/example.js
// ...
actions: {
  myButtonAction() {
    // call the controller action
    this.get('controllerActionThatWasPassedIn')(/* pass any data if necessary */);
  }
}

コントローラーに実際のストア操作を実行させ、必要に応じて結果をコンポーネントに戻します。

// controllers/example.js
// ...
actions: {
  handleData(someArgs) {
    this.get('store)'.findSomething(someArgs).then((result) => {
      this.set('result', result); // set the result which will automatically be passed down into the component
    });
  }
}

// templates/example.hbs
{{my-component result=result
               controllerActionThatWasPassedIn=(action "handleData")
}}

Ember では、この概念をData down, Actions upと呼びます。

このように渡されたアクションはクロージャー アクションと呼ばれ、実際には、returnそれらからも実行できるため、次のようなものも同様に機能します。

// inside components/example.js
// ...
actions: {
  myButtonAction() {
    // call the controller action
    this.get('controllerActionThatWasPassedIn')(/* pass any data if necessary */)
      .then((result) => {
        // do stuff with result
      });
  }
}

ルートからコンポーネントのjqueryウィジェットにイベントリスナーをアタッチするにはどうすればよいですか?

注: アンチパターン

Ember でこれを行う自然な方法は実際にはありません。これは主に、何かがレンダリングされる前にルートとコントローラーが作成されるためです。そのため、代わりに Route と Controller でこれを行いたくないでしょう。

ただし、おそらくコントローラーを必要とせず、Route でいくつかの迅速な/小さな DOM 操作のみを実行したい場合 (これは通常、アンチパターンであることに注意してください)、いつでもEmber Run Loopフックを使用して、何らかの操作をスケジュールすることができます。レンダリング後に発生する:

export default Ember.Route.extend({
  init() {
    this._super(...arguments);

    Ember.run.scheduleOnce('afterRender', () => {
      $('.my-component').click(/* ... */)
    });
  }
});

または、コンテンツをレンダリングした後、 renderTemplate()フックで直接これを行うことができます。

renderTemplate() {
  this.render();
  $('.my-component').click(/* ... */); // Probably shouldn't do this though
}
于 2016-09-07T15:43:15.870 に答える