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

Как перезагрузить асинхронный со ссылками hasMany отношения?

Допустим, что

Post = DS.Model.extend({
  comments: DS.hasMany({async: true})
})

Comment = DS.Model.extend({
  post: DS.belongsTo()
})

и я должен использовать функцию links, потому что в противном случае я получаю ошибку 414 из-за слишком большого количества комментариев к сообщению.

Поскольку это commit https://github.com/emberjs/data/commit/4d717bff53f8c93bedbe74e7965a4f439882e259

Кажется, что невозможно вызвать перезагрузку post.get('comments'), то есть отправить запрос GET, например post/42/comments.

Есть ли какое-либо решение для этого?

4b9b3361

Ответ 1

Благодаря @igorT это реализовано. https://github.com/emberjs/data/pull/2297

Теперь у ManyArray есть метод reload(), который вы даже можете вызвать, если отношение еще не загружено.

Вы можете увидеть некоторые примеры использования, прочитав tests

Ответ 2

UPDATE

Как и @sly7_7, в приведенном ниже ответе эта функция теперь доступна в данных ember-данных. Поэтому, если вы используете версию 1.0.0-beta.11 или выше, этот код не нужен

Вы можете снова открыть ManyArray и создать новый метод под названием reloadLinks(). Со следующим:

var get = Ember.get;

DS.ManyArray.reopen({
    reloadLinks: function() {
        var records = get(this, 'content'),
        store = get(this, 'store'),
        owner = get(this, 'owner'),
        type = get(this, 'type'),
        name = get(this, 'name'),
        resolver = Ember.RSVP.defer();

        var meta = owner.constructor.metaForProperty(name);
        meta.type = type;
        var link = owner._data.links[meta.key];
        store.findHasMany(owner, link, meta, resolver);
    }
});

Используется следующее:

comments.reloadLinks();

Посмотрите на этот скрипт http://jsfiddle.net/H6Gqf/

Ответ 3

Перезагрузка hasMany еще не встроена в Ember Data, но это на своем пути. Для решения, которое я использую, требуется Ember Data 1.0b9 + canary, который включает опровергать совпадающие находки.

Шаг 1: Входите.

Я выбрал уровень ApplicationAdapter, но вы можете сделать это на основе адаптера для каждой модели. Вот что у меня есть:

MyApp.ApplicationAdapter = DS.ActiveModelAdapter.extend({
  coalesceFindRequests: true
});

Чтобы дать вам представление о том, почему это важно и хорошо, на одной странице нашего приложения было до 50 запросов до этого изменения. Теперь мы видим только 11. Это все еще не здорово, но это один из улучшений!

Шаг 2: Перезагрузка записей в Ассоциации

Я просто завершаю перезагрузку в функции на моей модели следующим образом:

MyApp.SomeModel = DS.Model.extend({
  fooMany: DS.hasMany('foo', { async: true }),
  barMany: DS.hasMany('bar', { async: true }),
  bazOne: DS.belongsTo('baz', { async: true }),

  reloadAssociated: function () {
    var foosPromises = this.get('foos').invoke('reload'),
        barsPromises = this.get('bars').invoke('reload'),
        bazPromise = this.get('baz').reload();

    return Em.RSVP.hash({
      foos: foosPromises,
      bars: barsPromises,
      baz: bazPromise
    });
  }
});

Я признаю, что это не очень красиво, но это лучшее решение, которое я придумал до тех пор, пока перезагрузка не будет встроена в ассоциации.

Ответ 4

У меня была та же проблема, и я обманул, чтобы найти "решение"

i создал компонент "CommentLoader". Этот компонент принимает один аргумент (post_id) и перед "inserting" (willInsertElement) я отрисую все комментарии и сделаю их. это работает, но... я не горжусь этим: (

Ответ 5

С ember-data-1.0.0-beta.10 Я использую следующее расширение модели.

Просто вызовите model.reloadRelationship(name), где name - это имя атрибута model, представляющего отношение.

Это работает как для нормального, так и для ссылки принадлежит отношениям /hasMany.

DS.Model.reopen({
    reloadRelationship: function(name) {
        var meta = this.constructor.metaForProperty(name),
            link = this._data.links ? this._data.links[meta.key] : null;
        if (!link) {
            if (meta.kind === 'belongsTo') {
                this.get(name).then(function(model) { model.reload(); });
            } else {
                this.get(name).invoke('reload');
            }
        } else {
            meta.type = this.constructor.typeForRelationship(name);
            if (meta.kind === 'belongsTo') {
                this.store.findBelongsTo(this, link, meta);
            } else {
                this.store.findHasMany(this, link, meta);
            }
        }
    }
});

Единственное, что отсутствует здесь, - это некоторые проверки, например проверка, если модель уже перезагружается, когда модель перезагружается ссылкой или проверит, существует ли имя свойства в текущей модели.

EDIT ember-data-1.0.0-beta.14:

DS.Model.reopen({
    reloadRelationship: function(key) {
        var record = this._relationships[key];
        if (record.relationshipMeta.kind === 'belongsTo') {
            return this.reloadBelongsTo(key);
        } else {
            return this.reloadHasMany(key);
        }
    },
    reloadHasMany: function(key) {
        var record = this._relationships[key];
        return record.reload();
    },
    reloadBelongsTo: function(key) {
        var record = this._relationships[key];
        if (record.link) {
            return record.fetchLink();
        } else {
            record = this.store.getById(record.relationshipMeta.type, this._data[key]);
            return record.get('isEmpty') ? this.get(key) : record.reload();
        }
    }
});

Отношение HasMany будет возвращено к встроенному методу перезагрузки.

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

Ответ 6

Другой вариант - добавить метод к модели. Должен также работать на hasMany:

search: DS.belongsTo('search', {async: true})

updateSearch: ->
  resolver = Ember.RSVP.defer()
  resolver.resolve = =>
    # do something after promise resolves
  relationship = @constructor.metaForProperty('search')
  link = @_data.links[relationship.key]
  @store.findBelongsTo this, link, relationship, resolver