Ember的房产是什么?或者他们是方法吗?

时间:2013-09-04 19:09:55

标签: javascript ember.js

这可能是一个合法的愚蠢问题,但我觉得这让我无法理解Ember的大部分内容。

在以下代码中:

App.IndexRoute = Em.Route.extend({
  skipSidebar: true
});    

什么是'skipSidebar:'?关于javascript编程语言是什么,它在Ember中是什么?

另一个例子:

App.AboutRoute = Ember.Route.extend({
  activate: function(){
    this.controllerFor('application').set('renderAboutSubNav', true);
  },
  deactivate: function(){
    this.controllerFor('application').set('renderAboutSubNav', false);
  }
});

什么是'activate:'和'deactivate:'?

在第一个例子中,我使用'skipSidebar'来渲染部分:

{{#unless skipSidebar}}
   {{partial 'sidebar'}}
{{/unless}}

但我不确定为什么我这样做或者它在做什么。

基本上我看到路由和控制器内部看起来像方法的这些名称,我不知道它们来自哪里。如果有人能向我解释这一点,就好像我是一只非常棒的金毛猎犬。我什么时候可以使用它们?我应该什么时候使用它们?我该如何使用它们?

2 个答案:

答案 0 :(得分:1)

由于您评论说您熟悉OO编程,因此您应该很容易理解。

  

什么是'skipSidebar:'?关于javascript编程语言是什么,它在Ember中是什么?

App.IndexRoute = Em.Route.extend({
  skipSidebar: true
});    

在ember中,所有扩展例如是Ember.Object的子类,Ember.Object依次是基本类对象(基础),它为您提供OO风格编程所需的所有机制。所以在skipSidebar的情况下,这是一个分配到扩展Ember.Route对象的类属性,正如我所说的那样,它也是Ember.Object的子类。 所以现在想象你会扩展App.IndexRoute

App.MyFooRoute = App.IndexRoute.extend({
  someFunction: function() {
    this.get('skypSidebar'); // this would retrieve the correct property defined in App.IndexRoute
  }
});
  

什么是'activate:'和'deactivate:'?

App.AboutRoute = Ember.Route.extend({
  activate: function(){
    this.controllerFor('application').set('renderAboutSubNav', true);
  },
  deactivate: function(){
    this.controllerFor('application').set('renderAboutSubNav', false);
  }
});

在这种情况下,Ember.RouteEmber.Object已经提供的基本功能之上具有其他功能,在route的情况下,此附加功能主要与路由相关。为了让开发人员更容易生成,ember提供了一个所谓的公共API,它包含一个可以覆盖的存根函数,以便在其生命周期中调用此函数时得到通知。此函数也称为hooks。在activate和它的对应deactivate的情况下,当路由即将变为活动时,由ember调用/调用它,并且分别是非活动的,例如当路线改变时。

为了更进一步,想象一下你希望总是执行一些基本功能,但是你想要扩展类并覆盖这些钩子而不会丢失基本逻辑,那么有一种方法称为this._super()

App.BasicRoute = Ember.Route.extend({
  activate: function(){
    alert('route activated');
  },
  deactivate: function(){
    alert('route deactivated');
  }
});

现在我们扩展App.BasicRoute

App.DifferentRoute = App.BasicRoute.extend({
  activate: function(){
    this._super();
    // do stuff
  },
  deactivate: function(){
    this._super();
    // do atuff
  }
});

上面的例子会调用activate和它的父类的deactivate执行alert(...);,因为我们在子类中调用了this._super(),并且还执行了任何逻辑可能已在子类中定义。

希望它有所帮助。

答案 1 :(得分:1)

从纯Javascript语法的角度来看,这段代码:

App.IndexRoute = Em.Route.extend({
  skipSidebar: true
});

相当于这个Ruby:

App['IndexRoute'] = Em['Route'].extend( { 'skipSidebar' => true } );

也就是说,它将Hash的一个元素(在Javascript中所有对象基本上都是)分配给另一个Hash的元素上的方法调用的结果,其中一个参数是第三个Hash,这个在文字中form(JSON的基础)。

事实上,你可以用几乎与Ruby相同的形式编写JS:

App['IndexRoute'] = Em['Route'].extend( { skipSidebar: true } );

...因为Javascript中的Name.Key语法只是Name['Key']的便捷快捷方式,当密钥字符串是有效标识符时,它可以正常工作。这也有效:

App['IndexRoute'] = Em['Route']['extend']( { skipSidebar: true } );

因为Javascript就像Python一样,方法实际上只是属性(Hash元素),其值是函数/闭包。

然而,在语义上,这在Ember中正在做的是在IndexRoute对象(用于命名空间)中定义一个名为App的类作为Ember定义的类{{的子类。 1}}(在Route对象/命名空间中),并为所有新Em对象添加一个默认为skipSidebar的属性true。所以在功能上,它更像是Ruby:

App.IndexRoute

在你的第二个例子中:

class App::IndexRoute < Em::Route
  attr_accessor :skipSidebar
  def initialize
    @skipSidebar = true
  end
end

我们再次定义一个子类(此时间为App.AboutRoute = Ember.Route.extend({ activate: function(){ this.controllerFor('application').set('renderAboutSubNav', true); }, deactivate: function(){ this.controllerFor('application').set('renderAboutSubNav', false); } }); 而不是Ember.Route),并在子类中添加或覆盖两个名为Em.Routeactivate的方法。红宝石:

deactivate