EmberJS - 依赖注入

这是一个将一个对象的依赖项提供给另一个对象的过程,Ember 应用程序使用它来声明和实例化它们之间的对象和依赖项类。Ember.ApplicationEmber.ApplicationInstance 类在 Ember 的依赖注入实现中起着重要作用。

Ember.Application 类声明和配置对象并用作依赖项声明的"注册表",而 Ember.ApplicationInstance 类充当实例化对象的"所有者"。但是,Ember.Application 类充当应用程序的主要注册表,每个 Ember.ApplicationInstance 类都充当注册表。

工厂注册

工厂指定应用程序部分(如路由、模板等),并使用特定密钥进行注册。例如,索引模板用 template:index 定义,应用程序路由用 route:application 定义。

注册密钥包括两部分;一部分是工厂类型,另一部分是工厂名称,两部分用冒号 (:) 分隔。例如,您可以通过使用 logger:main 密钥 注册 Logger 工厂 来初始化应用程序。

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');

示例

下面给出的示例展示了 Ember 应用程序中工厂注册、注入和实例查找的使用。创建一个名为 dependency-inject 的组件,该组件将在 app/components/ 下定义。打开 dependency-inject.js 文件并添加以下代码 −

import Ember from 'ember';
var inject = Ember.inject;

export default Ember.Component.extend ({
   //在文件 /app/services/message.js 中加载服务
   message: inject.service(),
   message: 'Click the above button to change text!!!',
   actions: {
      pressMe: function () {
         
         //点击按钮后,上述消息将显示在控制台上
         var testText = this.get('start').thisistest();
         this.set('message', testText);
         //点击按钮后,进入组件页面
         this.get('logger').log('Entered in component!');
      },
      
      scheduleTasks: function () {
         //在特定队列(如"sync"或"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) {
   //将"start"属性注入到组件中
   app.inject('component', 'start', 'service:message');
}

export default {
   //初始化器名称
   name: 'init',
   initialize: initialize
};

创建一个可在应用程序不同部分使用的服务。使用以下命令创建服务 −

ember generate service message

现在使用以下代码打开在 app/services/ 下创建的 message.js 服务文件 −

import Ember from 'ember';

export default Ember.Service.extend ({
   isAuthenticated: true,
   //单击按钮后,将触发"thisistest()"并显示以下文本
   thisistest: function () {
      return "Welcome to Tutorialspoint!!!";
   }
});

接下来,创建一个初始化程序,在应用程序启动时对其进行配置。可以使用以下命令创建初始化程序 −

ember generate initializer logger

使用以下代码打开在 app/initializers/ 下创建的 logger.js 初始化程序文件 −

import Ember from 'ember';

//它是一个在应用程序启动时运行的应用程序初始化程序
export function initialize(application) {
   var Logger = Ember.Object.extend({
      log(m) {
         console.log(m);
      }
   });
   
   //注册密钥包含两部分:一是工厂类型,二是工厂名称
   application.register('logger:main', Logger);
   
   //一旦工厂注册完成,就可以使用"application.inject"进行注入
      along with 'logger' property 
   //此属性的值将来自"logger:main"工厂
   application.inject('component:dependency-inject', 'logger', 'logger:main');
}

export default {
   name: 'logger',
   initialize: initialize
};

接下来,使用以下命令为应用程序创建实例初始化程序 −

ember generate instance-initializer logger

使用以下代码打开在 app/instance-initializers/ 下创建的 logger.js 初始化程序文件 −

//应用程序实例初始化程序在应用程序实例加载时运行
export function initialize(applicationInstance) {
   var logger = applicationInstance.lookup('logger:main');
   
   //这表明实例已在控制台日志中启动
   logger.log('Hello...This message is from an instance-initializer!');
}

export default {
   //它是一个实例初始化器名称
   name: 'logger',
   initialize: initialize
};

输出

运行 ember 服务器;您将收到以下输出 −

Ember.js Dependency Injection

接下来,单击单击此处按钮,它将显示服务页面中的文本,如下面的屏幕截图所示 −

Ember.js Dependency Injection

现在转到控制台并检查在文本显示后从实例初始化程序显示的日志消息,如上面的屏幕截图所示 −

Ember.js Dependency Injection

接下来,单击计划任务按钮来安排按优先级顺序处理的队列上的工作 −

Ember.js Dependency Injection

emberjs_application_concerns.html