Emberjs:访问控制器对不同命名空间的依赖

时间:2013-07-10 21:08:52

标签: ember.js handlebars.js

在我的ember应用程序中,我希望在不同的命名空间上有模块。我有一个App Namespace,每个模块都有一个App.ModuleName命名空间。

到目前为止,我可以使用App/ModuleName/SomeResource语法访问目前为止的所有内容。现在我有一个控制器,它依赖于一个模块命名空间中的控制器。我把控制器放在这样:

App.ModuleName.FooController = Ember.Controller.extend({
    fooVal: 42
});

App.SomeController = Ember.Controller.extend({
    needs: ['App/ModuleName/Foo', 'bar']
});

到目前为止,这似乎有效,因为没有抱怨所需的控制器不存在。

现在,如何在我的车把模板中访问控制器?对于bar控制器而言,只需使用controllers.bar.someProperty即可轻松访问App.ModuleName.FooController。我试过了:

{{controllers.App/ModuleName/Foo.fooVal}}
{{controllers.App.ModuleName.Foo.fooVal}}
{{controllers.Foo.fooVal}}

等等,我能想到的每一个组合,但它都没有用。是否有可能(以及如何)运行?有人可以赐教我吗?

顺便说一句:即使在控制器上我成功使用needs,如果我调试它们(将它们直接登录到控制台,直接从我的代码或使用把手助手),controllers属性是总是undefined。有没有办法检查所需的控制器参考?

非常感谢提前。

2 个答案:

答案 0 :(得分:2)

据我所知,Ember的容器通过解析器查找内容。它只在应用程序的命名空间中查找内容。

DefaultResolver docs中的一些示例。

'controller:post' //=> App.PostController
'controller:posts.index' //=> App.PostsIndexController
'controller:blog/post' //=> Blog.PostController
'controller:basic' //=> Ember.Controller

要实现您的需求,您需要提供一个自定义Resolver,在创建应用程序时在不同的命名空间中查找内容。

App = Ember.Application.create({
  resolver: MyNewResolver
});

答案 1 :(得分:0)

对于我对如何解决问题以及我尝试和学习的内容感兴趣的所有人:

我在代码中做了一些挖掘并尝试了一些事情。我使用

获得了所需的输出

a)自定义Handlebars助手,它返回控制器的属性,如下所示:

{{ myhelper 'App.ModuleName.FooController' 'fooVal'}}

使用以下(快速和脏)帮助程序:

Ember.Handlebars.registerBoundHelper('myhelper', function(arg1, arg2, opts) {

    if (opts && opts['data']) {
        var ctrl = opts.data.properties[0];
        var prop = opts.data.properties[1];

        var controller = this.get('container').lookup('controller:' + ctrl.split('.').join('/'));
        if (controller) {
            return controller.get(prop);
        }
    }
});

问题是,我无法使数据绑定工作,所以如果我更改了我的基础模型,视图就不会更新。

b)重写控制器init()方法以获取如下控制器实例:

init: function() {
   this.module = this.get('container').lookup('controller:App/Module/Foo');
}

然后在模板中:

{{module.fooVal}}

在第二种方式中,数据绑定也有效,但它感觉不正确,所以我做了一些googlin并在emberjs问题列表上看到了这篇文章:

https://github.com/emberjs/ember.js/issues/683#issuecomment-5122333

正如tomdale所说,嵌套命名空间并不是ember鼓励的东西,但是多个'toplevel'命名空间都可以。所以我决定为每个模块设置一个顶级命名空间,并使用自定义解析器来解决它们。现在就像魅力一样,感觉就像是正确的做法。

我非常感谢有关我的第二种也是最后一种解决问题方法的专业人士和意见的任何其他建议和意见。