Глубокие ссылки Ember JS

У меня есть приложение Ember JS 1.5.1 с бета-версией ember-data 1.0.8. Есть ДВА простых скомпилированных шаблона, соответствующие части:

показатель

<div class="container-fluid">
    <div class="col-md-2 sidebar">
        <ul class="nav nav-sidebar">
            {{#each model}}
            <li>
                {{#link-to 'activities' this}}{{name}}{{/link-to}}
            </li>
            {{/each}}
        </ul>
    </div>
    <div class="col-md-10 col-md-offset-2">
        {{outlet}}
    </div>
</div>

виды деятельности

<div>
    <ul>
        {{#each model.activities}}
        <div class="row">
            <p>activity {{id}} is {{name}}</p>
        </div>
        {{/each}}
    </ul>
</div>

Приложение также простое, оно сводится к нескольким битам данных приборов и некоторым функциям маршрута:

window.App = Ember.Application.create();

App.ApplicationAdapter = DS.FixtureAdapter;

App.Router.map( function(){
    this.resource('index', {path: '/'}, function(){
        this.resource('activities', { path:':name'}, function(){
            this.resource('activity');
        });
    });
});

App.IndexRoute = Ember.Route.extend({
    model: function(){
        return this.store.find('role');
    }
});

App.ActivitiesRoute = Ember.Route.extend({
    model: function(params){ 
        var roles = this.modelFor('index');
        return roles.findBy('name', params.name).get('activites');
    }
});

App.Role = DS.Model.extend({
    name: DS.attr('string'),
    activities: DS.hasMany('activity', {async:true} )
});

App.Activity = DS.Model.extend({
    name: DS.attr('string')
});

App.Role.FIXTURES = [{
    id: 1,
    name: 'Management',
    activities: [1]
},{
    id: 2,
    name: 'Analysis',
    activities: [1,2]
},{
    id: 3,
    name: 'Development',
    activities: [2]
}]

App.Activity.FIXTURES = [{
    id: 1,
    name: 'talking'
},{
    id: 2,
    name: 'doing'
}];

Когда я перехожу к локальному хосту, я получаю простой список из трех ролей в левой части экрана и ничего в правой части. (как и ожидалось)

Когда я затем выбираю ссылку (например, «Анализ»), выход с правой стороны заполняется ожидаемым списком из двух названий действий «говорить» и «делать».

LHS list         RHS pane
==========       ======== 
Management       talking
Analysis         doing
Development

Все идет нормально.

Я заметил, что когда я наводил курсор на ссылку «Анализ», браузер показывает приведенный ниже URL, как и ожидалось.

localhost:/#/Analysis

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

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


person Code Uniquely    schedule 07.06.2014    source источник


Ответы (1)


Когда вы используете link-to и передаете ему модель, он пропускает хук модели, поставляющий модель из link-to в маршрут. Если вы обновите страницу, она будет обращаться к каждому маршруту вниз по дереву, пока не получит модели для каждого ресурса/маршрута, необходимые для выполнения запроса. Итак, если мы посмотрим на ваши маршруты по одному, это будет сделано так:

  1. Перейдите к маршруту приложения, выберите его модель, если она существует (маршрут приложения является корнем каждого приложения Ember).
  2. Пройдите по маршруту index, куда он вернется App.Role.find()
  3. Пройдите по маршруту activites, куда он вернется App.Activity.find()

Номер 3 - это то, где лежит ваша настоящая проблема. Независимо от того, говорит ли эта часть URL-адреса «Анализ», «Управление» или «Разработка», вы уже вернете App.Activity.find(). Вы определили динамический slug :name, ember проанализирует соответствующую часть URL-адреса и передаст эту часть как объект, в случае Analysis Ember передаст { name: 'Analysis' } к вашей модели. Вы захотите воспользоваться этим, чтобы вернуть правильную модель.

App.ActivitiesRoute = Ember.Route.extend({
    model: function(params){ 
       var roles = this.modelFor('index');
       return roles.findBy('name', params.name);
    }
});

Кроме того, вы используете довольно старую версию Ember Data. Вот небольшой пример того, как Ember Data следует использовать с более новыми версиями: http://emberjs.jsbin.com/OxIDiVU/617/edit

Как видите, вы больше не объявляете магазин. Кроме того, у вас могут возникнуть проблемы с тем, что считается асинхронными свойствами, и вы можете прочитать https://github.com/emberjs/data/blob/master/TRANSITION.md

person Kingpin2k    schedule 08.06.2014
comment
Обновлен до бета-версии ember-data и изменен App.Role для использования действий: вместо этого DS.hasMany('activity', {async:true} ). включил предложенный вами код, но пока var record = roles.findBy('name', params.name) получает объект, var result = record.get('activites'); возвращает неопределенное значение. В результате возвращаются нулевые записи, как и раньше (при глубокой ссылке) - person Code Uniquely; 08.06.2014
comment
можете ли вы добавить обновление над тем, как выглядит код, это сделает его немного более понятным, где вы делаете получение и т. д. - person Kingpin2k; 08.06.2014
comment
Я только что понял, помещая его в jsbin (я не закончил его подключать, вот начало, emberjs.jsbin.com/OxIDiVU/618/edit), что вы передаете всю ролевую модель маршруту действий, поэтому вам следует игнорировать .get('activites') в этом маршруте. Я бегу, но я закончу подключение, если это не решит проблему, когда я вернусь. - person Kingpin2k; 08.06.2014
comment
Вы абсолютно правы, и это сработало как шарм, спасибо - person Code Uniquely; 08.06.2014