13

ember を使用して管理ダッシュボードを構築しています。アプリケーション全体で複数のインスタンスを持つことができる再利用可能なチャート オブジェクトを作成したいと考えています。グラフ オブジェクトには、実際のグラフ (chart.js) を添付するために、DOM に挿入した後に ID が必要なマークアップと canvas 要素で構成されるテンプレートが必要です。いくつかのアプローチを試しましたが、これを行うための適切なアーキテクチャを理解できないようです。

上記を達成するための ember の適切なアーキテクチャは何でしょうか?

ありがとう!

4

2 に答える 2

34

Ember.Componentあなたの友達です

@raulbritoがすでに述べたように、emberで再利用可能なコンポーネントが必要な場合の最善の方法は、Webコンポーネントの新しいw3ドラフトにEmber.Component大きく基づいているため、将来の証明となる新しいものを使用することです。

これをどのように実装できるかについて、簡単な例を作成しようとしました。フックがいくつかの静的データを返す単純なroute場合:model

インデックス ルート

App.IndexRoute = Ember.Route.extend({
  model: function(){
    return Ember.Object.create({
      modelOne: data,
      modelTwo: data2
    });
  }
});

datadata2は単純化のためにグローバルに定義された単純な静的オブジェクト(デモでわかるように)ですが、これはバックエンドやフィクスチャなどからのデータである可能性もあります。

索引テンプレート

次に、テンプレートに線{{line-chart data=model.modelOne}}を含むチャート コンポーネントを挿入し、ご覧のとおり、属性をインデックス モデルまたは に設定しdataますmodel.modelOnemodel.modelTwo

<script type="text/x-handlebars" id="index">
  <h2>Chart one</h2>
  {{line-chart data=model.modelOne}}

  <h2>Chart two</h2>
  {{line-chart data=model.modelTwo}}
</script>

コンポーネント テンプレート

コンポーネント テンプレートは単純な要素をレンダリングするため、かなり単純に見えますcanvasが、必要に応じて複雑にすることもできます。使用方法については、ドキュメントEmber.Componentも参照してください。

<script type="text/x-handlebars" id="components/line-chart">
</script>

コンポーネント サブクラス

App.LineChartComponent = Ember.Component.extend({
  tagName: 'canvas',
  attributeBindings: ['width', 'height'],
  width: '480',
  height: '360',
  data: null,
  didInsertElement: function() {
    var ctx = this.get('element').getContext("2d");
    var myNewChart = new Chart(ctx).Line(this.get('data'));
  }
});

ここでは命名が重要であることに注意してください。Ember は、その名前に基づいて、どのサブクラスがコンポーネントを強化しているかを認識します。たとえば、 というコンポーネントがある場合、line-chartというサブクラスを作成しますApp.LineChartComponent。コンポーネントが呼び出されbar-chart-simpleた場合、クラス名は などになりApp.BarChartSimpleComponentます。Ember は、コンポーネントのキャメル化された名前の後に が続くクラスを探しますComponent

したがって、からEmber.Component拡張されEmber.Viewているため、あらゆる種類のプロパティを定義して、などをEmber.ViewサポートできますtagName。私たちの場合canvas、これが機能するchart.js必要があるため、使用します。ご覧のとおり、 ember 内のとのとattributeBindingsを制御するためにいくつか定義しました。コンポーネントには、後でフックから返されたテンプレートにモデル データを設定する定義済みの属性(適切な名前を付けることができます) もあります。そして最後に、コンポーネントのフックで、チャートを初期化し、データ オブジェクトとともに新しく作成されたクラスに渡します。widthheightcanvasdataIndexRoute modeldidInsertElementthis.get('data')Chart.js

var ctx = this.get('element').getContext("2d");
var myNewChart = new Chart(ctx).Line(this.get('data'));

最後になりましたが、上記の説明の実際のについては、こちらを参照してください。

それが役に立てば幸い。

最後のコメントに応じて更新する

フックの解決の遅延をシミュレートして、バックエンドからの応答を模倣しようとしました。最初にプロミスが解決さmodelれるのをテンプレートのレンダリングが待機していることがわかります。model基本的に私がやったことはEmber.run.later、タイムアウトした約束を解決する2000ミリ秒の遅延で使用することです:

App.IndexRoute = Ember.Route.extend({
  model: function(){
    return new Ember.RSVP.Promise(function(resolve) {
      Ember.run.later(function() {
        var m = Ember.Object.create({
          modelOne: data,
          modelTwo: data2
        });
        resolve(m);
      }, 2000);
    });
  }
});

そして、楽しみのためにLoadingRoute、Promise の解決がデータを待っている間にスピナーを表示する を追加しましLoadingRoute。 machty/5647589の下に、 Promise を使用した移行中に (グローバル) Loading Spinner を配置するにはどうすればよいですか?

更新された例については、こちらを参照してください: http://jsbin.com/odosoy/145/edit

@SamSelikoff のコメントに応じて更新

上記については、LoadingRoute@SamSelikoff は、公式に文書化されていることを指摘しました: http://emberjs.com/guides/routing/defining-your-routes/#toc_initial-routes

于 2013-08-28T11:22:21.750 に答える