Подтвердить что ты не робот

Почему моя модель маршрута ember.js не называется?

Я только начал изучать Ember.js(купил PeepCode screencast), и учусь от него довольно плавно, но столкнулся с проблемой при попытке написать свое первое приложение 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 - это идентификатор базы (база ВВС в Японии) 4c806eabd92ea093ea2e3872 - это идентификатор места на Foursquare

Когда маршрут маршрута попадает, я настраиваю данные с помощью вызова aps aps, а затем перебираю 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 screencast (на ~ 12: 25 в видео), он утверждает, что "контроллеры редко когда-либо совершают вызовы данных, объекты маршрута обрабатывают это", поэтому я думаю, что я прав, поставив свой ajax вызовы в маршрутах (я видел так много разных обучающих онлайн, но поскольку Peepcode консультировался с создателями Ember.js, я пошел с ним в качестве основного источника обучения).

Если это неверно или может быть сделано лучше, пожалуйста, дайте мне знать.

4b9b3361

Ответ 1

Документация Ember на крючке модели:

"Крючок, который вы можете реализовать для преобразования URL-адреса в модель для этого маршрут".

Это объясняет, почему крючок модели просто вызван при обновлении страницы. Но это смущает много людей:-). Таким образом, в этом случае это не правильный выбор. Я думаю, вы должны использовать hook 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}}. Вы передаете объект места на свой маршрут. Эмбер предполагает, что это тот же объект, который вы получите при выполнении вашего крючка модели. Итак, из Embers View нет необходимости вызывать крючок модели. Поэтому, если вы хотите выполнить логику поиска, даже если вы используете linkTo, используйте setupController hook.

Ответ 2

FYI:

Вы можете использовать крючок модели для такого рода вещей, просто передайте id вместо объекта:

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

Поскольку Ember больше не знает, какой объект связан с данным идентификатором, Ember вынужден перезагружать данные (поэтому Ember вызывает крючок модели).

Ответ 3

Основанный на ответе мавилейна, но более короткий и подходящий для Ember CLI с данными Ember...

import Ember from 'ember';

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

Также обратите внимание, что метод выборки доступен только из Ember Data 1.0.0-beta.12.

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