如何以及何时使用Ember.Application的register和inject方法?

62

我想了解如何使用Ember.Application registerinject方法。

这些函数设计用于什么样的情况?它们应该如何使用,何时使用?

我真的很想知道!

2个回答

94

Ember 默认使用约定来进行依赖注入,例如如果您使用 ember-data,则应用程序启动时会自动向每个路由和控制器注入 store 类的实例,因此您可以通过在任何路由或控制器中执行 this.get('store') 来获取对它的引用。

以下是一个代码片段示例,其中默认的 store 已注册(取自源码)。

Ember.onLoad('Ember.Application', function(Application) {
  Application.initializer({
    name: "store",

    initialize: function(container, application) {
      application.register('store:main', application.Store);
      ...
    }

    container.lookup('store:main');
  }
});

然后注入(来源

Application.initializer({
  name: "injectStore",

  initialize: function(container, application) {
    application.inject('controller', 'store', 'store:main');
    application.inject('route', 'store', 'store:main');
    application.inject('dataAdapter', 'store', 'store:main');
  }
  ...
});

换句话说,registerinject是用来注册依赖项并手动注入它们的方法。

假设您有一个Session对象,在应用程序启动后通过服务器请求进行填充,并且您希望在每个控制器中都有对它的引用,您可以这样做:

var App = Ember.Application.create({
  ready: function(){
    this.register('session:current', App.Session, {singleton: true});
    this.inject('controller', 'session', 'session:current');
  }
});

App.Session = Ember.Object.extend({
  sessionHash: ''
});

这段代码将为每个控制器实例的 session 属性设置一个单例实例 App.Session,因此您可以在任何控制器中执行 this.get('session') 并获取对它的引用,并且由于它被定义为单例,它将始终是相同的 session 对象。

使用register可以注册控制器、模型、视图或任何其他类型的任意对象。另一方面,inject 可以注入到给定类的所有实例上。例如,inject('model', 'session', 'session:current') 还会将 session 属性与 session:current 实例一起注入到所有模型中。要将 session 对象注入到 IndexView 上,您可以执行 inject('view:index', 'session', 'session:current')

尽管 registerinject 非常强大,但您应该明智地使用它们,只有在确实知道没有其他方式可以实现您的目标时才使用它们,我想缺乏文档是一个不鼓励使用的指标。

更新-没有工作示例就没有好的解释

由于提供带有解释的工作示例大多数情况下是必须的,因此这里有一个示例:http://jsbin.com/usaluc/6/edit。请注意,在示例中,我们可以通过在每个路由中引用当前控制器的会话对象 {{controller.session.sessionHash}} 来简单地访问所提到的 sessionHash ,这是我们在应用程序中为每个控制器注册和注入了 App.Session 对象所做的工作的价值。

希望对您有所帮助。


2
我正在为Ember.js构建一个交互式的备忘单,你介意我把这个放在上面吗?你可以在这里看到它:http://embersherpa.com/ 它可能会放在Em.Application.register和Em.Application.inject下面。你觉得呢? - Taras Mankovski
@tarasm,很好的想法,制作备忘单-继续前进!如果你遇到Ember.Component,你也可以使用我刚刚写完的答案:https://dev59.com/0GMl5IYBdhLWcg3wV1wF - intuitivepixel
@tarasm,我的Twitter账号与我在SO上的昵称相同intuitivepixel。然而,我在那里并不是很活跃,但这种情况仍然可能会改变 :) - intuitivepixel
我跟着你。开始从来不会太晚 :) - Taras Mankovski
1
@Martin::main:current等只是标签。如果您有多个具有略微不同实现的相同对象要注册,例如myObject:basic,MyObjectBasic ...myObject:advanced,MyObjectAdvanced ...,则它们非常有用。希望这样说得清楚了? - intuitivepixel
显示剩余7条评论

8

嗨,Michael,我终于有机会再次查看所有内容了。感谢您的示例,我已经收藏了您的库。 - Taras Mankovski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接