javascript - Ember.js中的視圖與組件



handlebars.js (4)

現在看來 - v2.x是當前的穩定版本 - 視圖已被完全棄用。 據說從Ember 2.0 API中刪除了視圖

因此,在Ember 2.0中使用{{view}}關鍵字會觸發一個斷言:

聲明失敗:在Ember 2.0中刪除了使用{{view}}或其基於它的任何路徑

如果您必須在Ember 2.0中使用視圖,則可以使用ember-legacy-views插件,該插件將與Ember兼容,直到版本2.4

因此,總結 - 組件是現在(視圖被刪除)和未來 - 他們也將取代控制器。 請參閱可路由組件RFC

我正在學習ember.js,我試圖理解視圖和組件之間的區別。 我認為這是製造可重用組件的一種方式。

從Ember的網站上查看:

Ember.js中的視圖通常僅由於以下原因而創建:
- 當你需要復雜的用戶事件處理
- 當你想創建一個可重用的組件

從Ember的組件網站:

組件是一個自定義HTML標記,您的行為使用JavaScript實現,其外觀使用Handlebars模板描述。 它們允許您創建可以簡化應用程序模板的可重用控件

那麼視圖和組件之間的主要區別是什麼? 什麼是我喜歡使用組件視圖的常見示例,反之亦然?


Ember.View

Ember.View目前僅限於由W3C為您創建的標籤。 但是,如果您想定義自己的特定於應用程序的HTML標籤,然後使用JavaScript實現其行為? 你不能用Ember.View來做到這Ember.View

Ember.Component

這正是組件允許你做的事情。 實際上,W3C目前正在開發自定義元素規範,這是一個好主意。

Ember的組件實現嘗試盡可能地接近Web組件規範。 一旦自定義元素在瀏覽器中廣泛使用,您應該能夠輕鬆地將您的Ember組件遷移到W3C標準,並讓它們可以被其他框架使用,並且已經採用了新標準。

這對我們非常重要,我們正在與標準組織密切合作,以確保我們的組件實現與Web平台的路線圖相匹配。

另外需要注意的是, Ember.Component實際上是一個Ember.View (一個子類),但它是完全孤立的 。 其模板中的屬性訪問轉到視圖對象,動作也針對視圖對象。 沒有對周圍context或外部controller訪問權限, 所有上下文信息都被傳入 ,而Ember.View並不是這種情況,而Ember.View確實可以訪問它的周圍控制器,例如在視圖內部,你可以做類似this.get('controller') ,它會給你當前與視圖關聯的控制器。

那麼視圖和組件之間的主要區別是什麼?

因此,除了組件之外的主要區別是您可以創建自己的標籤,並且在自定義元素可用時的某個時間點,也可以在支持自定義元素的其他框架中遷移/使用這些組件,實際上在某些時候,一個支持組件的組件將根據具體的實施情況而使視圖稍微過時。

什麼是我喜歡使用組件視圖的常見示例,反之亦然?

以上這些依賴於你的用例。 但作為一個經驗法則,如果您需要在您的視圖中訪問其周圍的控制器等,請使用Ember.View ,但是如果您想要隔離視圖並僅傳遞其需要的信息,使其與上下文無關和更多的可重用,使用Ember.Component

希望能幫助到你。

更新

隨著Road to Ember 2.0的發布,您現在被鼓勵在大多數情況下使用組件而不是視圖。


答案很簡單: 使用組件

根據2013年8月錄製的培訓視頻,Yehuda Kats和Tom Dale(Ember核心團隊成員)告訴觀眾,除非您是框架開發人員,否則不會使用視圖。 他們對Handlebars進行了大量改進,並引入了組件,因此視圖不再是必需的。 視圖在內部用於支持諸如{{#if}}和{{outlet}}之類的內容。

組件也非常模仿將被構建到瀏覽器中的Web組件標準,所以在構建Ember組件時有很多好處。

更新2014-11-27

現在使用組件而不是視圖更為重要,因為輸入路由時Ember 2.0將使用可路由組件,而不是控制器/視圖。 為了將來驗證您的應用,最好遠離Views。

資料來源:


默認情況下,Ember在使用大多數約定引導應用程序時執行依賴注入,例如,如果使用ember-data,則應用程序中的每個routecontroller都會注入store類的實例,因此您以後可以通過簡單地獲取引用在任何路由或控制器中執行this.get('store')

例如,這裡是一個代碼提取,其中默認store get已註冊(取自source

Ember.onLoad('Ember.Application', function(Application) {
  Application.initializer({
    name: "store",

    initialize: function(container, application) {
      application.register('store:main', application.Store);
      ...
    }

    container.lookup('store:main');
  }
});

然後注入( source

Application.initializer({
  name: "injectStore",

  initialize: function(container, application) {
    application.inject('controller', 'store', 'store:main');
    application.inject('route', 'store', 'store:main');
    application.inject('dataAdapter', 'store', 'store:main');
  }
  ...
});

換句話說, registerinject是註冊依賴項並自己注入它們的方法。

假設您有一個Session對象,您在應用程序啟動時請求服務器請求後填充該對象,並且您希望在每個控制器中有一個引用,您可以執行以下操作:

var App = Ember.Application.create({
  ready: function(){
    this.register('session:current', App.Session, {singleton: true});
    this.inject('controller', 'session', 'session:current');
  }
});

App.Session = Ember.Object.extend({
  sessionHash: ''
});

此代碼將每個控制器實例的session屬性設置為App.Session的單例實例,因此您可以在任何控制器中執行this.get('session')並獲取對它的引用,因為它被定義為單例將始終是相同的session對象。

使用register您可以註冊控制器,模型,視圖或任何任意對像類型。 另一方面,注入可以注入給定類的所有實例 。 例如, inject('model', 'session', 'session:current')也會將會話屬性與session:current實例注入所有模型。 要注入session對象,讓我們說在IndexView你可以inject('view:index', 'session', 'session:current')

雖然registerinject非常強大,但你應該明智地使用它們,只有在你真正知道沒有其他方法可以實現你的目標的情況下,我想缺乏文檔是一個沮喪的指標。

更新 - 沒有一個有效的例子沒有好的解釋

因為提供一個解釋的工作示例大多是必須的,所以它是: http://jsbin.com/usaluc/6/edithttp://jsbin.com/usaluc/6/edit 。 請注意,在示例中,我們可以通過在我們所處的每個路徑中使用{{controller.session.sessionHash}}引用當前控制器的會話對象來簡單地訪問提到的sessionHash ,這是我們通過註冊和注入所做的工作的優點應用程序中每個控制器中的App.Session對象。

希望能幫助到你。





javascript ember.js handlebars.js