如何为服务以外的东西创建注入助手?
How to create a inject helper for something other than service?
在我上面引用的行中,ember-核心团队导入了这个 createInjectionHelper 并使用它来添加一个 clean/simple api 用于注入服务,例如
App.ApplicationRoute = Ember.Route.extend({
authManager: Ember.inject.service('auth'),
model: function() {
return this.get('authManager').findCurrentUser();
}
});
我如何为非服务自己创建这样的东西?
我认为他们无意让您以这种方式使用它。如果您使用的是普通 ember,则标准方法是使用 App.inject(),如果您使用的是 ember-cli.
,则在初始化程序中执行此操作
你的情况:
// Register the service
App.register('service:auth', {
findCurrentUser: function() {
// Do your magic
}
}, { instantiate: false });
App.inject('route', 'auth', 'service:auth');
然后在你的模型挂钩中你可以使用this.auth.findCurrentUser();
。如果需要,您也可以将其注入控制器和组件。另请注意,为了保持简洁,您可能希望包含一个单独的模块,而不是在服务注册中定义您的 auth 模块。
更多信息在这里:
注意
服务也不是 "special" 的东西。您可以使用此方法将任何您想要的东西注入到几乎任何您想要的东西中。
您的示例用法将与上面的稍有不同。我们稍后会介绍 injectRepositories 的作用。
import injectRepositories from 'app/utils/inject';
export default Ember.Route.extend({
repository: injectRepositories('person'),
model: function() {
var repository = this.get('repository');
return repository.find();
}
});
可以通过以下更改改进初始化程序:
import registerWithContainer from "ember-cli-auto-register/register";
export function initialize(_, application) {
registerWithContainer("repositories", application);
application.inject("repositories", "store", "store:main");
}
export default {
name: "repositories",
after: "store",
initialize: initialize
};
让我们分解每一行中发生的事情。
registerWithContainer("repositories", application);
在上面的行中,我们推迟到 ember-addon ember-cli-auto-register。这个插件将获取一个目录,在这种情况下,repositories
目录并将每个对象注册到 Ember 容器中,以便能够通过查找访问。它们将被插入,就像执行以下操作一样:
application.register("repositories:person", PersonRepository);
然后我们添加一个函数来使用 ember-addon ember-cli-injection:
进行注入
// app/utils/inject.js
import inject from "ember-cli-injection/inject";
var injectRepositories = inject("repositories");
export default injectRepositories;
这让我们有机会使用上面新创建的函数通过下面的代码访问这些对象:
import injectRepositories from 'app/utils/inject';
export default Ember.Route.extend({
repository: injectRepositories('person'),
model: function() {
var repository = this.get('repository');
return repository.find();
}
});
由于每个对象现在都在容器中,我们可以在运行时而不是在应用程序初始化期间查找并注入它。我们在函数中注册了 repositories
键,然后 returns 计算出的 属性 (参见下面来自 ember-cli-injection 的代码)。我们将其作为计算 属性 来执行以允许延迟加载。在访问 属性 之前,不会从容器中提取对象。
import Ember from 'ember';
var injection = function(key) {
return function(name) {
return Ember.computed(function(propertyName) {
var objectName = name || propertyName;
return this.container.lookup(key + ':' + objectName);
});
};
};
export default injection;
我们还允许将名称传递给存储库函数,例如 repository: injectRepositories('person')
。这允许您在注入时随意命名您的对象。
如果您只想将对象命名为与注入到容器中的存储库名称相同的名称,您可以选择 person: injectRepositories()
。这会将 person
密钥作为 propertyName
传递给计算的 属性 并且由于在注入时名称被保留 null
, objectName
将改为 person
。这匹配 API 产生类似的结果,但与 Ember.inject.service
和 Ember.inject.controller
API 的结果不同,Ember 1.10 可用。
在我上面引用的行中,ember-核心团队导入了这个 createInjectionHelper 并使用它来添加一个 clean/simple api 用于注入服务,例如
App.ApplicationRoute = Ember.Route.extend({
authManager: Ember.inject.service('auth'),
model: function() {
return this.get('authManager').findCurrentUser();
}
});
我如何为非服务自己创建这样的东西?
我认为他们无意让您以这种方式使用它。如果您使用的是普通 ember,则标准方法是使用 App.inject(),如果您使用的是 ember-cli.
,则在初始化程序中执行此操作你的情况:
// Register the service
App.register('service:auth', {
findCurrentUser: function() {
// Do your magic
}
}, { instantiate: false });
App.inject('route', 'auth', 'service:auth');
然后在你的模型挂钩中你可以使用this.auth.findCurrentUser();
。如果需要,您也可以将其注入控制器和组件。另请注意,为了保持简洁,您可能希望包含一个单独的模块,而不是在服务注册中定义您的 auth 模块。
更多信息在这里:
注意
服务也不是 "special" 的东西。您可以使用此方法将任何您想要的东西注入到几乎任何您想要的东西中。
您的示例用法将与上面的稍有不同。我们稍后会介绍 injectRepositories 的作用。
import injectRepositories from 'app/utils/inject';
export default Ember.Route.extend({
repository: injectRepositories('person'),
model: function() {
var repository = this.get('repository');
return repository.find();
}
});
可以通过以下更改改进初始化程序:
import registerWithContainer from "ember-cli-auto-register/register";
export function initialize(_, application) {
registerWithContainer("repositories", application);
application.inject("repositories", "store", "store:main");
}
export default {
name: "repositories",
after: "store",
initialize: initialize
};
让我们分解每一行中发生的事情。
registerWithContainer("repositories", application);
在上面的行中,我们推迟到 ember-addon ember-cli-auto-register。这个插件将获取一个目录,在这种情况下,repositories
目录并将每个对象注册到 Ember 容器中,以便能够通过查找访问。它们将被插入,就像执行以下操作一样:
application.register("repositories:person", PersonRepository);
然后我们添加一个函数来使用 ember-addon ember-cli-injection:
进行注入// app/utils/inject.js
import inject from "ember-cli-injection/inject";
var injectRepositories = inject("repositories");
export default injectRepositories;
这让我们有机会使用上面新创建的函数通过下面的代码访问这些对象:
import injectRepositories from 'app/utils/inject';
export default Ember.Route.extend({
repository: injectRepositories('person'),
model: function() {
var repository = this.get('repository');
return repository.find();
}
});
由于每个对象现在都在容器中,我们可以在运行时而不是在应用程序初始化期间查找并注入它。我们在函数中注册了 repositories
键,然后 returns 计算出的 属性 (参见下面来自 ember-cli-injection 的代码)。我们将其作为计算 属性 来执行以允许延迟加载。在访问 属性 之前,不会从容器中提取对象。
import Ember from 'ember';
var injection = function(key) {
return function(name) {
return Ember.computed(function(propertyName) {
var objectName = name || propertyName;
return this.container.lookup(key + ':' + objectName);
});
};
};
export default injection;
我们还允许将名称传递给存储库函数,例如 repository: injectRepositories('person')
。这允许您在注入时随意命名您的对象。
如果您只想将对象命名为与注入到容器中的存储库名称相同的名称,您可以选择 person: injectRepositories()
。这会将 person
密钥作为 propertyName
传递给计算的 属性 并且由于在注入时名称被保留 null
, objectName
将改为 person
。这匹配 API 产生类似的结果,但与 Ember.inject.service
和 Ember.inject.controller
API 的结果不同,Ember 1.10 可用。