在视图助手中传递mixin

时间:2013-03-15 03:26:45

标签: ember.js handlebars.js

在Ember中,我们在模板中使用了很多视图帮助器。我想知道,如果有一种简单的方法可以在帮助程序执行时将mixin传递给Ember.View类(View正在创建)。

http://jsbin.com/ekuxal/2/edit

这样的东西

模板示例:

{{view Ember.TextField mixins="App.Console"}}

Mixin的例子:

App.Console = Ember.Mixin.create({
   didInsertElement: function(){
     this._super();
     console.log('from the mixin');
   }
});
来自mixin 的

将登录到控制台。

有这样的东西是否有意义?

由于

2 个答案:

答案 0 :(得分:0)

从我的观点来看,这个要求对我来说毫无意义。为什么? 在扩展类时使用Mixins,因为它们是实现多重继承的一种方式。因此它们在数据和逻辑建模期间使用。 视图助手用于实例化视图类的对象。我认为,可以通过编写自定义帮助程序并在其中使用 createWithMixins()来完成。但是在模板中做这些事似乎很困惑。

您能否再详细说明一下您的要求?它真的只是关于记录吗?

更新:实施建议

我通过source code of the view helper阅读以评估是否可行。这不是Ember的开箱即用功能,但可以通过覆盖Ember View帮助器中的某些逻辑来实现。

假设你有这个模板:

{{view App.YourView mixin="App.YourMixin"}}

对帮助程序最重要的是实例Ember.ViewHelper,它包含要修改的逻辑。可以尝试重新打开它并修改相关部分,如下所示:

var EmberHandlebars = Ember.Handlebars;
EmberHandlebars.ViewHelper.reopen({
  helper: function(thisContext, path, options) {
    var inverse = options.inverse,
        data = options.data,
        view = data.view,
        fn = options.fn,
        hash = options.hash,
        newView;

    if ('string' === typeof path) {
      newView = EmberHandlebars.get(thisContext, path, options);
      Ember.assert("Unable to find view at path '" + path + "'", !!newView);
    } else {
      newView = path;
    }

    // NEW CODE FOR MIXIN LOGIC
    if(hash.mixin){
      var newViewClass = newView; // newView should be the class App.YourView here
      var yourMixin = Ember.get(hash.mixin); //get the Mixin by name
      var newViewInstance = newView.createWithMixins(yourMixin); //create the view with mixin
      newView = newViewInstance; // assign the view to the variable where the rest of the logic is expecting it
    }

    Ember.assert(Ember.String.fmt('You must pass a view to the #view helper, not %@ (%@)', [path, newView]), Ember.View.detect(newView) || Ember.View.detectInstance(newView));

    var viewOptions = this.propertiesFromHTMLOptions(options, thisContext);
    var currentView = data.view;
    viewOptions.templateData = options.data;
    var newViewProto = newView.proto ? newView.proto() : newView;

    if (fn) {
      Ember.assert("You cannot provide a template block if you also specified a templateName", !get(viewOptions, 'templateName') && !get(newViewProto, 'templateName'));
      viewOptions.template = fn;
    }

    // We only want to override the `_context` computed property if there is
    // no specified controller. See View#_context for more information.
    if (!newViewProto.controller && !newViewProto.controllerBinding && !viewOptions.controller && !viewOptions.controllerBinding) {
      viewOptions._context = thisContext;
    }

    currentView.appendChild(newView, viewOptions);
  } 
});

注意:我自己还不能测试这个逻辑。 更新:已成功测试!

答案 1 :(得分:0)

在这种情况下,我会扩展Ember的TextField视图来创建自己的自定义视图,并将mixin添加到javascript中扩展视图的位置。例如:

TEMPLATE:

{{view 'MyTextField'}} // Custom view that extends Ember.textField

查看:

App.MyTextFieldView = Em.TextField.extend(App.MyMixin, { // Add your mixin to Ember's TextField view here
    // Any further view code here (optional because this view already has all the functions of Ember's text field view and you've mixed in your other functionality in the line above).
});

MIXIN:

App.MyMixin = Em.Mixin.create({
    // Your mixin code here
});