Внедрить службу в объект Ember [не Ember Controller]

Я пытаюсь внедрить службу Ember в объект Ember, но продолжаю получать следующую ошибку:

"Assertion Failed: Attempting to lookup an injected property on an
object without a container, ensure that the object was instantiated 
via a container."

Мой код выглядит примерно следующим образом:

const Model = Ember.Object.extend({
  store: Ember.inject.service(),

  destroyRecord() {...},

  serialize() {...},

  deserialize() {...},
});

let newModel = Model.create();
newModel.get('store');

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

Ответ 1

Он работает для Ember.Controller, потому что Ember управляет жизненным циклом объекта. Короче говоря, когда Ember нуждается в экземпляре определенного контроллера, он запрашивает контейнер для одного, и контейнер предоставит экземпляр, при необходимости инициализируя.

Это означает, что для инъекции зависимостей вам нужно будет получить новый экземпляр Model через контейнер. Предполагая Ember 2.3 из-за getOwner и что this находится где-то внутри приложения Ember:

let owner = Ember.getOwner(this);
let newModel = owner.lookup('object:model');
newmodel.get('store');

Здесь вы можете ознакомиться с документацией lookup.

Но как зарегистрироваться? Используйте инициализатор приложения:

$ ember generate initializer register-model

Затем откройте сгенерированный инициализатор и, предположив, что ваш файл находится в app/folder/model.js, поместите что-то вроде:

import Model from 'app-name/folder/model';

export function initialize(application) {
  application.register('object:model', Model);
}

export default {
  name: 'register-model',
  initialize
};

Здесь вы можете ознакомиться с документацией register.

Надеюсь, что это будет полезно!

Ответ 2

Ну, вам нужно передать экземпляр контейнера при создании экземпляра вашей модели. Контейнер доступен на маршруте, контроллерах, компонентах с this.get('controller'). AFAIK в основном все, что создано с контейнером, получает свойство контейнера. Вот почему сервисные инъекции работают в контроллерах и т.д.

Итак, если вы создаете модель в методе маршрута. Код будет выглядеть ниже

App.IndexRoute = Ember.Route.extend({
  model: function() {
    var newModel = Model.create({
      container: this.get('container')
    });    
    return newModel.get('test').getText();
  }
});

Вот рабочая демонстрация.