依赖注入(Dependency Injection)
它是一个将一个对象的依赖项提供给另一个对象并由Ember应用程序用于声明和实例化它们之间的对象和依赖项类的过程。 Ember.Application和Ember.ApplicationInstance类在Ember的依赖注入实现中起着重要作用。
Ember.Application类声明并配置对象并用作依赖性声明的“注册表”,其中Ember.ApplicationInstance类充当实例化对象的“所有者”。 但是, Ember.Application类充当应用程序的主注册表,每个Ember.ApplicationInstance类充当注册表。
工厂注册
工厂指定应用程序部分,例如路径,模板等,并使用特定密钥进行注册。 例如,索引模板使用template:index定义,应用程序路由使用route:application定义。
注册码包括两部分; 一个是工厂类型,第二个是工厂名称,两个段用冒号(:)分割。 例如,您可以通过使用logger:main key注册Logger factory来初始化应用程序。
application.register('mylog:logmsg', MyLogger);
工厂注射
一旦注册,工厂就可以注入。 例如,请考虑以下代码 -
application.inject('route', 'mylog', 'mylog:logmsg');
所有类型的路由工厂都将使用mylog属性表示,此属性的值将来自mylog:logmsg工厂。 您也可以使用全键注入特定工厂 -
application.inject('route:index', 'mylog', 'mylog:logmsg');
这里只有mylog属性会被注入索引路由。
工厂实例查询
您可以在应用程序实例上使用工厂实例的lookup方法,以从正在运行的应用程序中获取实例化的工厂。 它使用字符串来确定工厂并返回一个对象。
例如,您可以在应用程序实例上调用lookup方法来获取实例化的工厂,如下所示 -
applicationInstance.lookup('factory-type:factory-name');
例子 (Example)
下面给出的示例显示了在Ember应用程序中使用工厂注册,注入和实例查找。 创建一个名为dependency-inject的组件,它将在app/components/下定义。 打开dependency-inject.js文件并添加以下代码 -
import Ember from 'ember';
var inject = Ember.inject;
export default Ember.Component.extend ({
//load the service in the file /app/services/message.js
message: inject.service(),
message: 'Click the above button to change text!!!',
actions: {
pressMe: function () {
//after clicking button, above message will get display at console
var testText = this.get('start').thisistest();
this.set('message', testText);
//after clicking button, it will enter in the component page
this.get('logger').log('Entered in component!');
},
scheduleTasks: function () {
//scheduling work on specific queues like "sync" or "afterRender"
Ember.run.schedule('afterRender', this, function () {
console.log("CUSTOM: I'm in afterRender");
Ember.run.schedule('sync', this, function () {
console.log("CUSTOM: I'm back in sync");
});
});
}
}
});
现在打开组件模板文件app/templates/components/dependency-inject.hbs并输入以下代码 -
<button {{action "pressMe"}}>Click Here</button><br>
<h2>{{message}}</h2>
<button {{action "scheduleTasks"}}>Schedule Tasks!</button>
{{yield}}
打开application.hbs文件并添加以下代码行 -
{{dependency-inject}}
{{outlet}}
我们需要使用以下命令创建一个初始化程序来配置应用程序 -
ember generate initializer init
打开在app/initializers/下创建的init.js文件,并添加以下代码 -
export function initialize(app) {
//injecting the 'start' property into the component
app.inject('component', 'start', 'service:message');
}
export default {
//initializer name
name: 'init',
initialize: initialize
};
创建可在应用程序的不同部分中使用的服务。 使用以下命令创建服务 -
ember generate service message
现在打开在app/services/下创建的message.js服务文件,其中包含以下代码 -
import Ember from 'ember';
export default Ember.Service.extend ({
isAuthenticated: true,
//after clicking the button, 'thisistest()' triggers and display the below text
thisistest: function () {
return "Welcome to xnip!!!";
}
});
接下来,创建一个初始化程序,在启动时配置应用程序。 可以使用以下命令创建初始化程序 -
ember generate initializer logger
使用以下代码打开在app/initializers/下创建的logger.js初始化文件 -
import Ember from 'ember';
//it is an application initializer that run as your application boots
export function initialize(application) {
var Logger = Ember.Object.extend({
log(m) {
console.log(m);
}
});
//Registration key includes two parts; one is factory type and second is
name of factory
application.register('logger:main', Logger);
//Once a factory is registered, it can be injected by using 'application.inject'
along with 'logger' property
//and value for this property will come from 'logger:main'factory
application.inject('component:dependency-inject', 'logger', 'logger:main');
}
export default {
name: 'logger',
initialize: initialize
};
接下来,使用以下命令为应用程序创建实例初始值设定项 -
ember generate instance-initializer logger
使用以下代码打开在app/instance-initializers/下创建的logger.js初始化文件 -
//Application instance initializers run as an application instance is loaded
export function initialize(applicationInstance) {
var logger = applicationInstance.lookup('logger:main');
//it indicates that instance has booted at console log
logger.log('Hello...This message is from an instance-initializer!');
}
export default {
//it is an instance initializer name
name: 'logger',
initialize: initialize
};
输出 (Output)
运行ember服务器; 你会收到以下输出 -
接下来,单击Click Here按钮,它将显示服务页面中的文本,如下面的屏幕截图所示 -
现在转到控制台并检查日志消息,这些消息在文本显示后从实例初始化程序显示,如在abve屏幕截图中一样 -
接下来,单击schedule Tasks按钮以计划按优先级顺序处理的队列的工作 -