当从模板调用时,二级服务不会被注入

EmberJS Second level of service are not injected when calling from template

本文关键字:服务 二级 注入 调用      更新时间:2023-09-26

从模板(例如onClick={{action myFirstLevel.hello}})调用业务函数时,应该注入myFirstLevel的服务留在undefined

通过组件操作调用正在工作。

<button onClick={{action myFirstLevel.hello}}>Hello Service</button>
<button onClick={{action 'hello'}}>Hello Action</button>

App = Ember.Application.create();
App.MyFirstLevelService = Ember.Service.extend({
  mySecondLevel: Ember.inject.service(),
  hello: function() {
    console.log('Hello first level');
    this.get('mySecondLevel').hello();
  }
});
App.MySecondLevelService = Ember.Service.extend({
  hello: function() {
    console.log('Hello second level');
  }
});
App.MyButtonComponent = Ember.Component.extend({
  myFirstLevel: Ember.inject.service(),
  actions: {
    hello:  function() {
      this.get('myFirstLevel').hello();
    }
  }
});

http://emberjs.jsbin.com/conaxaheno/1/edit?html, js、控制台、输出

myFirstLevel.hello函数将通过MyButtonComponent调用此上下文,因此当您在服务中执行this.get('mySecondLevel')时,它将返回undefined,因此要使其工作,您应该将mySecondLevel服务包含到组件

App.MyButtonComponent = Ember.Component.extend({
  myFirstLevel: Ember.inject.service(),
  mySecondLevel: Ember.inject.service(),
  actions: {
    hello:  function() {
      this.get('myFirstLevel').hello();
    }
  }
});

您可以使用hack。但是,除非你必须这样做,否则不建议这样做。我相信在你的情况下,最理想的方法是使用第二个按钮选项,但如果你绝对确定自己在做什么,你可以冒险一试:

App.MyFirstLevelService = Ember.Service.extend({
  mySecondLevel: Ember.inject.service(),
  hello: function() {
    console.log('Hello first level');
    Ember.getOwner(this).lookup('service:my-first-level').get('mySecondLevel').hello()
  }
});

这个函数实际上会在你点击按钮时被调用,但它会在组件的上下文中被调用,这不是你想要的,因为当你瞄准this时,你会访问组件作用域。

另一个选项是

App.MyFirstLevelService = Ember.Service.extend({
      mySecondLevel: Ember.inject.service(),
      hello: function() {
        console.log('Hello first level');
        this.get('myFirstLevel.mySecondLevel').hello()
      }
});

中,您可以避免与所有者混淆,但它仍然完全不可读。您能做的最好的事情就是坚持在组件作用域中定义操作,并从模板中调用它们。这些动作反过来可以为你获得任何深度的服务和触发功能。

@kumkanillam是对的,语境不对。要设置它,可以使用target=,但onClick=...似乎不起作用。

所以正确的语法是<button {{action myFirstLevel.hello target=myFirstLevel}}>Hello Service</button> https://github.com/emberjs/ember.js/issues/14334