我知道JS并非旨在“干净地”处理每个OOP的继承,但是我想知道Ember是否有办法实现这一目标。

在Ember中,我认为Ember.ObjectController.extend({...});是某种继承,但不是完全继承-我们当然可以添加我们自己的属性和方法,因此可以添加函数.extend({...}),但不能“覆盖”已存在的函数。我想知道是否有这样的解决方法。

如果创建了基本控制器,如何定义希望子控制器实现的功能?我有基本控制器(仅理论代码):

App.BaseController = Ember.ObjectController.extend({
     // Methods meant for a child controller to implement
     abstractMethod1: null,
     abstractMethod2: null,
     virtualMethod1: function(){
         ...
     },
     actions: {
        execute: function(){
             if(this.get("abstractMethod1"))
                 this.get("abstractMethod1")();
             ...
             if(this.get("abstractMethod2")
                 var x = this.get("abstractMethod2")();
        }
    }
});


然后,我有一个实现控制器试图覆盖这些功能:

App.ImplementingController = App.BaseController.extend({
    /* How would I implement abstractMethod1 and abstractMethod2 here!?
       For virtualMethod1, how would I call something like base.virtualMethod1()
       or super.virtualMethod1()?
    */
});


我发现自己创建了很多具有基本相同代码的控制器,除了模型的名称及其属性之外。能够在Ember中提出该计划将是很好的。该怎么办?

最佳答案

实际上,Ember可以很好地完成工作,您只需不重写它就可以实现基本实现。或者,您可以重写它,从而使基本实现无效。 (实际上,这也是Mixins的工作方式,http://emberjs.com/api/classes/Ember.Mixin.html)。如果您想点击base函数,属性等,则可以使用它进行访问(本质上是将这两个类粉碎在一起,优先于扩展类。

基础

App.BaseController = Ember.ObjectController.extend({
  a:'Base',
  b:'Base',
  acomp: function(){
    return 'Base';
  }.property(),
  bcomp: function(){
    return 'Base';
  }.property(),
  e:function(){
    return 'Base';
  },
  f:function(){
    return 'Base';
  }
});


扩展的

App.IndexController = App.BaseController.extend({
  b:'Index',
  c:'Index',
  bcomp: function(){
    return 'Index';
  }.property(),
  f:function(){
    return 'Index';
  },
  actions:{
    foo:function(){
      console.log(this.e());
      console.log(this.f());
    }
   }
});


Ember合并它们后的外观

App.IndexController....
      a:'Base'
      b:'Index',
      c:'Index',
      acomp: function(){
        return 'Base';
      }.property(),
      bcomp: function(){
        return 'Index';
      }.property(),
      e:function(){
        return 'Base';
      },
      f:function(){
        return 'Index';
      },
      actions:{
        foo:function(){
          console.log(this.e());
          console.log(this.f());
        }
       }
    });


http://emberjs.jsbin.com/wuhuleje/2/edit

07-24 09:50
查看更多