2016-01-24 5 views
10

Ich versuche, ein Ember Dienst in ein Ember Objekt zu injizieren, aber halten den folgenden Fehler erhalten:Injizieren Sie einen Dienst in einem Ember Object [kein Ember Controller]

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

Mein Code sieht im Wesentlichen so etwas wie die folgende:

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

    destroyRecord() {...}, 

    serialize() {...}, 

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

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

Hinweis: es funktioniert, wenn ich den Dienst in einen Controller zu injizieren, aber kein Objekt. Hab kein Glück gehabt, herauszufinden, wie man das Objekt mit dem Ember-Container registriert.

Antwort

17

Es funktioniert für eine Ember.Controller weil Ember den Lebenszyklus des Objekts steuert. Kurz gesagt, wenn Ember eine Instanz eines bestimmten Controllers benötigt, fragt es den Container nach einem, und der Container stellt die Instanz zur Verfügung und initialisiert sie gegebenenfalls.

Dies bedeutet, dass für die Abhängigkeitsinjektion eine neue Instanz von Model über den Container abgerufen werden muss. Unter der Annahme, Ember 2.3 wegen getOwner, und dass this ist irgendwo in der Ember Anwendung:

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

Sie die lookup documentation here einsehen können.

Aber wie man sich anmeldet? Verwenden Sie eine Anwendung initializer:

$ ember generate initializer register-model 

Dann öffnen die erzeugte initializer und unter der Annahme, dass die Dateien in app/folder/model.js ist, setzen Sie so etwas wie:

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

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

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

Sie können die register documentation here konsultieren.

Hoffe, das ist hilfreich!

+1

Also, um zu klären, Registrierung von Objekten, die nicht bereits Teil des Ember-Lebenszyklus (in meinem Fall, Modelle), ist mit dem Initialisierer gemacht. Um die Modellklasse an anderer Stelle in der App aufzurufen, rufen Sie 'Ember.getOwner (this) .lookup ('object: model')' auf, yeah? (Der Suchaufruf ruft offensichtlich die Model-Klasse zurück und ruft '.create()' darauf auf). In meinem Fall funktionierte das Importieren von Dateien über "Import Model from" path/to/model; ganz einfach über alle wichtigen Dateien, da ich immer noch mit statischen Methoden interagieren konnte. –

+1

Kurz gesagt, ja. Sie müssen sie nicht wirklich registrieren, es sei denn, Sie möchten, dass Ember den Lebenszyklus verwaltet, also ist 'Importieren' in Ordnung, wie Sie sagten. Wenn Sie näher diskutieren wollen, ping mich in der Slack-Gruppe! – locks

+0

Tatsächlich, nach einem anderen Blick, realisiere ich einfach über 'Import Model von' path/to/model 'importieren; 'wowo eine Suche aus einem bereits registrierten Objekt über' Ember.getOwner (this) .lookup (...) 'wirft immer noch den gleichen Fehler auf. Ich werde mich auf Slack freuen, wenn ich mich über mich aufrege. –

-1

Nun, Sie müssen die Container-Instanz übergeben, wenn Sie eine Instanz Ihres Modells erstellen. Der Container ist in der Route, Controller, Komponenten mit this.get('controller') erreichbar. AFAIK grundsätzlich alles, was mit dem Container erstellt wird, bekommt die Container-Eigenschaft festgelegt. Das ist der Grund, warum Service-Injektionen in Controllern usw. funktionieren.

Also, wenn Sie das Modell in einer Route-Methode erstellen. Der Code wird wie folgt aussehen

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

Here is a working demo.

Verwandte Themen