这可能是一个合法的愚蠢问题,但我觉得这让我无法理解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}}
但我不确定为什么我这样做或者它在做什么。
基本上我看到路由和控制器内部看起来像方法的这些名称,我不知道它们来自哪里。如果有人能向我解释这一点,就好像我是一只非常棒的金毛猎犬。我什么时候可以使用它们?我应该什么时候使用它们?我该如何使用它们?
答案 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.Route
在Ember.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.Route
和activate
的方法。红宝石:
deactivate