亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

[Tips on Ember 2] How components works when out of

jk_v1 / 1558人閱讀

摘要:因為組件的存在范圍被限制在以內(nèi),這就是這種機制目前存在的意義所在。組件都是可以傳遞參數(shù)或外部作用域的,利用此機制進行判斷來執(zhí)行可選行為,這是對用戶友好的舉措。

這一篇還是一個簡單的例子所引發(fā)的思考。

你看,如今的框架和庫,無論規(guī)模大小功能多少,它們在本質(zhì)上都朝著“組件化”的思路快速演進著。Angular 有 directives,Angular 2應(yīng)該也還是這個叫法;Ember 從 View 過渡到了 Component,并且接下來的迭代會朝向 WebComponent 的標準來設(shè)計生命周期及其 API;React 自身就是一個組件化的范式;還有 Polymer,那就是 Google 為 WebComponent 搞得一套 polyfills……大家都這么玩。

我們都無法完整精確的預(yù)測 WebComponent 能讓 Web 進化到什么程度,但是現(xiàn)在已經(jīng)有了這么多可用的工具了,大家自然是躍躍欲試的搞起。我也沒有例外,在之前使用 Angular 的時候就在盡力做組件的抽象,把 directives 那一套算是玩兒轉(zhuǎn)了——那個時候并沒有意識到一件事情,直到最近返回 Ember 之后才開始有所體會。幾天前我在 Ember Community 提了個問題來討論此事,雖然也得到很多建議卻還是模模糊糊的;后來又和 @darkbaby123 詢問了一番,感謝他給了我很多啟迪。然而始終沒有想到一個確切的應(yīng)用場景來驗證一番。

說了半天估計你們都看糊涂了:到底什么事情啊?

Components 用來封裝可重用的 HTML+CSS+JavaScript 片段,這很好,然而當下的框架們都要處理事件委托的問題,這就意味著框架會給你一個范圍來開發(fā)你的應(yīng)用,這個范圍的邊界就是框架用于事件委托的臨界線,出了這條線就是瀏覽器自身的事件處理機制在作用了。那么,當你不得不“邁過”這條線的時候,框架(以及它提供的組件化機制)該如何幫助你呢?

舉例來說,Angular 的邊界在你聲明 ng-app 的地方(所以我見過不少人把它放在 上來擴大這個界限);Ember 默認在 上,當然你可以改;React 也是一樣,你總是要把你的第一個 component 渲染到 下面。那么,當你要做的事情超出 body 之外,它們應(yīng)該如何處理呢?

對于像 jQuery 這樣以 DOM 為中心(當然還有 BOM)的工具來說,這個問題很簡單——以 DOM 為中心就意味著瀏覽器有什么你就用什么,無非就是它原生的 API 不好用或不夠用,你拿過來用 jQuery 封裝一下就好了,換湯不換藥。所以當你要操作 body 以外的東西,原生的東西隨便你用,比如 document(DOM),比如 window(BOM) 等等,你唯一要做的就是外面套一個 $() 殼子。

在我們的大腦模型里已經(jīng)習慣了把 HTML 和 DOM 視為一體,但除此之外 DOM 和 BOM 還提供了豐富的接口來處理很多額外的事情,每一個框架或庫都會多多少少提供這些額外接口的封裝,比如 Angular 里的 $cookie$location,甚至干脆徹底的 $document$window,然而當這些東西和 component 關(guān)聯(lián)在一起的時候,事情會變得微妙起來:什么可以做不可以做?何時/何處來做?這些問題的界線變得搖擺不定。

Angular 有 DI(依賴注入)的機制,在 directives 的層面上,它巧妙的設(shè)計了一個 Attribute Level 的 directive 定義,通過 DI 你可以把超出 body 以外的操作通過 HTML 的屬性綁定給其他的 Tag Level 的 directives。因為組件的存在范圍被限制在 body 以內(nèi),這就是這種機制(目前)存在的意義所在。我們還不知道當 WebComponents 塵囂落定之時會給出我們怎樣的答案,當然屆時 JavaScript 已經(jīng)有了 modules,所以全局污染的問題已經(jīng)不復存在,現(xiàn)在唯一不明朗的就是如何與組件的生命周期關(guān)聯(lián)起來。

讓我們來看一個例子?,F(xiàn)在有很多應(yīng)用都有這樣的設(shè)計:Header 與 Main Content 沒有明顯的界限,看起來像一個整體。但如果 Main Content 的內(nèi)容超出了瀏覽器一屏的高度,那么當用戶向下滾動的時候,Header 會“浮”起來(通過下放的陰影)并固定在窗口頂部,很不錯的視覺效果。

問題就在于監(jiān)聽用戶滾動事件的動作應(yīng)該是發(fā)生在 BOM 范圍內(nèi)的,如果你的應(yīng)用是基于以組件為中心的思想開發(fā)的,這個動作到底應(yīng)該在哪里做?

這個問題其實會有很多變數(shù),比如說你可以設(shè)想這個動作和任何具體的組件無關(guān),而是在應(yīng)用程序初始化的時候直接執(zhí)行。很好,但是有兩個問題:

固定 Header 并為它添加陰影是需要 Header 已經(jīng)存在于 DOM 之中的,通常在應(yīng)用程序初始化的時候這個條件尚未達成

這個動作并不是發(fā)生在全局范圍之內(nèi)的,比如說某個路由進入之后或某種組件渲染之后才發(fā)生

以上任意一點都可以否決初始化執(zhí)行這個方案,如果你考慮長遠和周全一些的話就必須另尋出路。

好,我不廢話了,先把最近用 Ember 完成的這個例子代碼寫出來,最后我再說一點對此的想法吧。

第一步,把 Header 抽象為組件

這個很簡單,直接 ember generate component app-header 就好了,代碼略過。

第二步,在組件渲染之后執(zhí)行監(jiān)聽用戶向下滾動的事件并為組件添加 class,這個 class 完成了陰影等效果。
const SCROLL_THRESHOLD = 50  // header" height is 50px

export default Ember.Component.extend({
  classNameBindings: ["sticky"],
  didInsertElement() {
    window.addEventListener("scroll", () => {
      if (window.scrollY >= SCROLL_THRESHOLD) {
        this.set("sticky", true)
      } else {
        this.set("sticky", false)
      }
    }
  }
})
第三步,當組件銷毀后,注銷監(jiān)聽回調(diào)

這就可以發(fā)生在 body 以外的操作能和組件的生命周期緊密聯(lián)系在一起。這一點很重要,不管你用 Ember 還是 Angular/React,一定要注意組件的生命周期,特別是組件銷毀時這些框架都會提供對應(yīng)的 hook,要注意清理“垃圾”,移除綁定,釋放內(nèi)存等等,避免內(nèi)存泄漏。

const SCROLL_THRESHOLD = 50  // header" height is 50px

function _stickHeaderHandler() {
  if (window.scrollY >= SCROLL_THRESHOLD) {
    this.set("sticky", true)
  } else {
    this.set("sticky", false)
  }
}

export default Ember.Component.extend({
  classNameBindings: ["sticky"],
  didInsertElement() {
    window.addEventListener("scroll", _stickHeaderHandler.bind(this))  // remember to bind!!!
  },
  willDestroyElement() {
    window.removeEventListener("scroll", _stickHeaderHandler)
  }
})
DONE

我們還可以怎樣改進它呢?問題有二:

組件不應(yīng)該固化特殊的行為,如果這個組件是跨應(yīng)用共享的(比如你發(fā)布成 Addon),那么其他應(yīng)用可能是不需要置頂?shù)氖褂谜咂谕氖侨缦碌目蛇x項:

{{app-header stickyOnScroll=50}}

監(jiān)聽滾動那一套行為如果不是組件特有的(這就派出了發(fā)步成 Addon 的條件)而是應(yīng)用內(nèi)共享的,則應(yīng)該想辦法抽象出去——監(jiān)聽滾動這個事情很典型

對于問題一,答案已經(jīng)揭示在那里了。組件都是可以傳遞參數(shù)或外部作用域的,利用此機制進行判斷來執(zhí)行可選行為,這是對用戶友好的舉措。

對于問題二,在 Ember 里你至少有三個選項:

抽象成 Mixin。這個很直觀,缺點是 Mixin 提供的屬性不是 default value,它不能由你主動去覆蓋,不夠靈活;

定義成新的 Component。需要繼承的其他組件可以 extend 它,解決 Mixin 不夠靈活的問題,局限是只能給組件用——不過對于處理瀏覽器事件和操作 DOM/BOM 已夠用了;

抽象成 Service。這個等價于 Angular 的 DI,可以由你自己定義豐富的接口來配置和調(diào)用,最靈活,適合封裝需要的外部接口等等。

關(guān)于 Service,具體的代碼先 hold,以后我會專門講 Service 在 Ember 里的用法。今天這個例子不適合抽象 Service,原因就是上面的第二點。

當我在幾天前對此還很困惑時,我一度認為像 Angular 的 Attribute Level Directives 才是處理此類問題的最佳方案,然而 WebComponent 并沒有 Attribute Level Component 這種設(shè)計,這也是我困惑的最初原因?,F(xiàn)在想一想,Attribute Level Directives 等于無視組件的生命周期(當然它有自己的生命周期,但是和要附著的目標組件無關(guān),你得管理兩份),它把可選行為附著于目標組件的過程等同于你創(chuàng)建一個新的特殊的 Service(特殊之處就在于它可以放在模版里),然后利用這個 Service 去寫實現(xiàn)代碼并且還可以再 DI 其他的 Services,以此來實現(xiàn)可選性和可復用性。這種設(shè)計乍看討巧但也有很多缺點,比如說多個 directives 共存的時候要考慮優(yōu)先級和行為覆蓋的問題,比如說和未來的 WebComponents 不兼容改造起來很費事,等等。

現(xiàn)在我們看到,React 一開始做得就很不錯(后起之秀借鑒了很多前輩們的經(jīng)驗教訓),不過它只是一個渲染引擎,做大型應(yīng)用還需要你在整體架構(gòu)上下功夫;Ember 的架構(gòu)很完整,以前的問題很多但現(xiàn)在都在一一完善,設(shè)計思路沒有什么錯誤,拿來做 UI 交互復雜的 web 應(yīng)用的確是很不錯的選擇。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/85991.html

相關(guān)文章

  • React Native Vs. Xamarin Vs. Ionic Vs. Flutter

    React Native Vs. Xamarin Vs. Ionic Vs. Flutter:Which Is Best For Cross-Platform Mobile App Development? While developing Native Mobile Apps, Android apps are written in Java, and iOS ones in Swift and...

    Clect 評論0 收藏0
  • [Tips on Ember 2] 如何嘗試 angle-bracket component

    摘要:警告版本是很不穩(wěn)定的,并不推薦使用于要上線的應(yīng)用。如果你要嘗試新的特性,要么是新建一個測試用的,要么是你的應(yīng)用離正式上線還早并且你和你的團隊折騰得起。在此功能正式發(fā)布之后應(yīng)該是不需要這段補丁代碼的,目前來說也不會影響使用。 Ruby China 的朋友大概都知道我很喜歡 Ember,然而我用 Ember 的經(jīng)歷其實遠比不上 Angular 那么豐富(Ember 業(yè)余愛好,Angular...

    Yu_Huang 評論0 收藏0
  • [Tips on Ember 2] Ember CLI with Webstorm

    摘要:好,你用就用吧,各種問題自己也不會看文檔問谷歌,成天怨聲載道的不得不吐槽一下現(xiàn)在的年輕人。為什么使用有關(guān)和的糾結(jié)歷史可以去谷歌一下,此處不再啰嗦最根本的原因就是對的支持更好,更新和維護也更勤快。 Tips on Ember 2 對我來說是沒什么計劃性的寫作,我只是把它當做是每天工作的總結(jié)日志,一個很重要的目的是為團隊做一些技術(shù)事務(wù)的整理,以幫助一些新人快速成長起來。如果有些內(nèi)容不能滿足...

    curlyCheng 評論0 收藏0
  • 使用REACT VR構(gòu)建web虛擬現(xiàn)實

    Building virtual reality experiences on the web with React VR Over the past year, virtual reality has made major strides toward becoming the next computing platform. With Oculus Rift, consumer-grade h...

    anquan 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<