Ember.js связывает приложение с реальным API после успеха Mirage

По мере того, как я погружаюсь все глубже и глубже в процесс создания приложений Ember.js, я натыкаюсь на другую стену.

До того, как я с большим успехом использовал Mirage — я просто копировал вывод из API, который я хотел создать, в приборы Mirage, и он отлично работал.

Теперь у меня проблема с тем, чтобы заставить его работать с реальным API.

Сначала я отключил мираж в config/environment.js.

ember g adapter filter

import ApplicationAdapter from './application';
export default ApplicationAdapter.extend({
    findAll: function(store, type, label) {
        var url = `${this.host}/${this.namespace}/${type.modelName}`;
        console.log(`${url}`);
        return this.ajax(url, 'GET');
    },
});

Адаптер приложения выглядит так

import DS from 'ember-data';

export default DS.JSONAPIAdapter.extend({
    host: 'http://127.0.0.1:1234',
    namespace: 'api',

    headers: Ember.computed(function(){
        return {"secret": "1234"};
    })
});

И таким образом, когда я вхожу /filter app/routes/filter/index

import Ember from 'ember';

export default Ember.Route.extend({
        model() {
                    return this.store.findAll('filter');

        }
});

Я вижу, что URL-адрес построен нормально, как http://127.0.0.1:1234/api/filter, и нет 404, но я получаю сообщение об ошибке

Error while processing route: filter.index The adapter operation was aborted EmberError@http://127.0.0.1:4200/assets/vendor.js:29616:15

и поскольку я не полностью понимаю ноу-хау Ember Inspector, я пытаюсь как-то понять это

Моя модель фильтра, которая работала раньше (с миражом), выглядит так:

import DS from 'ember-data';

export default DS.Model.extend({
        name: DS.attr(),
        url: DS.attr()
});

API возвращает список [{"id":1, "name": "namex", "url": "http://"},{"id":2, "name": "namey", "url": "http://"}]

Я уверен, что API возвращает данные так, как это не «фильтрует», поскольку раньше у меня были проблемы с множественным числом.

Изменить: ЭТО РЕШАЕТ ПРОБЛЕМУ

import DS from 'ember-data';

export default DS.RESTSerializer.extend(
{
        normalizeFindAllResponse(store, type, payload) 
        {
                var data = [];
                payload.forEach(
                    function(item, index, enumerable) 
                    {
                        var ob = {};
                        Ember.set(ob, 'id', item.id);
                        Ember.set(ob, 'type', 'filter');
                        Ember.set(ob, 'attributes', item);
                        data[index]=ob;
                        console.log(data[index]);
                    }
                );
                return {
                        data: data
                };
        }
});

Это почти исправление, но не совсем. Я могу получить доступ к некоторым атрибутам модели, таким как имя, но есть объект массива с 3 массивами внутри, 2 из них являются массивами, один посередине - Getter (что бы это ни было), и я не могу получить к нему доступ, поскольку это больше не массив. Поэтому я не уверен, правильно ли он привязывается к объекту таким образом. Также я не мог ничего сделать с «данными», потому что независимо от того, какой RESTAdapter здесь и там я ставил, он игнорировал его и запрашивал объект с атрибутом data/meta/errors... не знаю, ошибка это или нет.


person BigRetroMike    schedule 16.11.2016    source источник


Ответы (1)


Поскольку вы используете JSONAPIAdapter, ваш ответ API должен соответствовать спецификации формата JSON.

{      
  "data": [{
    "type": "filter",
    "id": "1",
    "attributes": {
      "name": "namex",
      "url": "http://"    
    }
  }, {
    "type": "filter",
    "id": "2",
    "attributes": {
      "name": "namey",
      "url": "http://"
    }
  }]
}

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

import DS from 'ember-data';

export default DS.RESTAdapter.extend({
    host: 'http://127.0.0.1:1234',
    namespace: 'api',

    headers: Ember.computed(function(){
        return {"secret": "1234"};
    })
});

Ответ RESTAdapter будет выглядеть так:

{"filters":[{"id":1, "name": "namex", "url": "http://"},{"id":2, "name": "namey", "url": "http://"}]}

либо вам нужно отправить его, как указано выше, либо манипулировать им для создания требуемого формата (переопределить normalizeFindAllResponse)

person Ember Freak    schedule 16.11.2016
comment
Я меняю адаптер на RESTAdapter, как вы предложили, поскольку я не могу изменить вывод API, но это не помогло. Все та же ошибка о прерывании. Нужно ли мне как-то манипулировать данными из API? или есть какая-то принудительная привязка? - person BigRetroMike; 16.11.2016
comment
Обновил мой ответ. Обычно приходит {"fitlers":[{}]}, но в вашем случае вы переопределили findAll, поэтому вы можете попробовать с {"fitler":[{}]} - person Ember Freak; 16.11.2016
comment
Единственная проблема, которая у меня есть, заключается в том, что если я устанавливаю export default ApplicationSerializer.extend({ normalizeFindAllResponse(store, type, payload) { return {data:payload};}, у меня появляется ошибка, сообщающая мне, что должен быть атрибут «данные», «ошибка» или «мета», поскольку ему нужна структура, которую вы публикуете для jsonapi, которую я изменяю в адаптерах/application.js как вы написали . - person BigRetroMike; 16.11.2016
comment
Я не делал этого раньше, но вам нужно убедиться, что normalizeFindAllResponse возвращает точный формат. в настоящее время для json-api ваш код не работает. но для RESTAPI ваш код может работать, если вы return {'data':payload}, а также убедитесь, что сериализатор приложения должен расширять RESTSerializer. - person Ember Freak; 16.11.2016
comment
его возврат {фильтры: полезная нагрузка}, поскольку полезная нагрузка представляет собой массив объектов - person BigRetroMike; 16.11.2016
comment
Хорошо, тогда RESTAdapter будет работать. Если нет, мы что-то упускаем. будем надеяться, что кто-нибудь просветит нас. Я надеюсь, что вы решите это. - person Ember Freak; 16.11.2016
comment
Я добавил app/serializers/filter.js в сообщение с вопросом. Я почти там, но еще нет. - person BigRetroMike; 16.11.2016
comment
В вашем обновленном коде вы можете попробовать это `payload = {data: data}; вернуть this._super(store, primaryModelClass, payload, id, requestType);` - person Ember Freak; 16.11.2016
comment
поскольку ваше предложение и помощь дали мне правильное направление, я отметил ваш пост как ответ. спасибо, кодировка, которую я добавил в редактирование, решает мою проблему, поскольку сеттер-получатель просто существует, но под ним есть данные, когда вы запрашиваете его. - person BigRetroMike; 16.11.2016