web-dev-qa-db-ja.com

ember.jsルートモデルが呼び出されないのはなぜですか?

Ember.js(PeepCodeスクリーンキャストを購入)の学習を始めたばかりで、非常にスムーズに学習していますが、最初のEmberアプリを作成しようとしたときに、問題が発生しました。

(ネストされた)ルートマッピングは次のとおりです。

App.Router.map(function () {
    this.resource('bases', { path: '/' }, function () {
        this.resource('base', { path: ':base_id' }, function () {
            this.resource('places', function () {
                this.resource('place', { path: ':place_id' });
            });
        });
    });
});

これにより、次のようなURLが許可されます:domain.com /#/ yokota-ab-japan/places/4c806eabd92ea093ea2e3872

yokota-ab-japanは基地(日本の空軍基地)のIDです4c806eabd92ea093ea2e3872はFoursquareの会場のIDです

Placesルートがヒットしたら、foursquare apiを呼び出してデータを設定し、JSONを反復処理してApp.Placeオブジェクトの配列を作成し、その配列を返します。

App.PlacesRoute = Ember.Route.extend({
    model: function () {
        var placesData = Ember.A();
        $.getJSON('https://api.foursquare.com/v2/venues/search?ll=35.744771,139.349456&query=ramen&client_id=nnn&client_secret=nnn&v=20120101',
            function (data) {
                $.each(data.response.venues, function (i, venues) {
                    placesData.addObject(App.Place.create({ id: venues.id, name: venues.name, lat: venues.location.lat, lng: venues.location.lng }));
                });
            });

        return placesData;
    }
});

それはうまくいくようです。このテンプレートを使用してplacesData配列を表示します。

<script type="text/x-handlebars" data-template-name="places">
    <div>
        {{#each place in controller}}
            {{#linkTo 'place' place}}
                {{place.name}}
            {{/linkTo}}
        {{/each}}
    </div>

    {{outlet}}
</script>

linkToは個々の場所にリンクしており、場所の詳細を表示したいと思います。単一の場所に関するデータをプルし、単一のApp.Placeオブジェクトにデータを入力して、それを返すように設定したルートは次のとおりです。

App.PlaceRoute = Ember.Route.extend({
    model: function (params) {
        console.log('place route called');

        var place;
        $.getJSON('https://api.foursquare.com/v2/venues/' + params.place_id + '?client_id=nnn&client_secret=nnn',
            function (data) {
                var v = data.response.venue;
                place = App.Place.create({ id: v.id, name: v.name, lat: v.location.lat, lng: v.location.lng });
            });

        return place;
    }
});

私の問題は、ユーザーがリンクをクリックしてもPlaceRouteが呼び出されないことですが、このルートでページが更新されると呼び出されます。

PeepCode Ember.jsスクリーンキャスト(ビデオの12:25まで)によると、「コントローラーがデータを呼び出すことはめったになく、ルートオブジェクトがそれを処理する」と述べているので、ajax呼び出しをに入れるのは正しいと思いますルート(オンラインでさまざまなチュートリアルを見てきましたが、PeepcodeがEmber.jsの作成者に相談したので、それを主要な学習ソースとして使用しました)。

これが正しくない場合、またはもっとうまくできる場合は、私に知らせてください。

29
Chaddeus

モデルフックに関するEmberドキュメント:

「URLをこのルートのモデルに変換するために実装できるフック。」

これは、モデルフックがページの更新時に呼び出される理由を説明しています。しかし、これは多くの人々を混乱させます:-)。したがって、この場合、これは正しいフックではありません。この場合、setupControllerフックを使用する必要があると思います。これを試して:

App.PlaceRoute = Ember.Route.extend({
    setupController: function (controller, model) {
        console.log('place route called');

        var place;
        $.getJSON('https://api.foursquare.com/v2/venues/' + model.get('place_id') + '?client_id=nnn&client_secret=nnn',
            function (data) {
                var v = data.response.venue;
                place = App.Place.create({ id: v.id, name: v.name, lat: v.location.lat, lng: v.location.lng });
            });

        controller.set("model", place);
    }
});

私からさらに2セント:アプリがURL /直接ブラウザーナビゲーションを介して入力されたときに、モデルフックが実行されたのはなぜですか?

Emberには、{{linkTo}}を使用する場合、必ずしもモデルフックを呼び出す必要はないという前提があります。プレイステンプレートでは、{{#linkTo 'place' place}} {{place.name}} {{/linkTo}}を使用します。プレイスオブジェクトをルートに渡します。 Emberは、これがモデルフックの実行時に取得するオブジェクトと同じであると想定しています。したがって、Embersビューからモデルフックを呼び出す必要はありません。したがって、linkToを使用している場合でも取得ロジックを実行する場合は、setupController hookを使用してください。

49
mavilein

Emberでモデルフックを使用するように強制します。オブジェクトの代わりにIDを渡すだけです:

{{#link-to 'place' place.id}}
    {{place.name}}
{{/link-to}}

Emberは、指定されたIDに関連するオブジェクトがわからなくなったため、Emberはモデルフックを呼び出します(したがって、データはサーバーからロードされます)。

17

Mavileinの回答に基づいていますが、より短く、Ember CLI with Ember Data .. ..

import Ember from 'ember';

export default Ember.Route.extend({
  setupController: function( controller, model ) {
    controller.set( "model", this.store.fetch( 'place', model.id ) );
  },
});

また、fetchメソッドはEmber Data1.0.0-beta.12からのみ使用可能であることに注意してください。

http://emberjs.com/api/data/classes/DS.Store.html#method_fetch

3
Keith Broughton