国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

jk_v1 / 1491人閱讀

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

第一步,把 Header 抽象為組件

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

第二步,在組件渲染之后執行監聽用戶向下滾動的事件并為組件添加 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)
      }
    }
  }
})
第三步,當組件銷毀后,注銷監聽回調

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

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

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

組件不應該固化特殊的行為,如果這個組件是跨應用共享的(比如你發布成 Addon),那么其他應用可能是不需要置頂的使用者期望的是如下的可選項:

{{app-header stickyOnScroll=50}}

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

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

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

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

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

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

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

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

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

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/85991.html

相關文章

  • 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

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

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

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

    curlyCheng 評論0 收藏0
  • 使用REACT VR構建web虛擬現實

    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

發表評論

0條評論

jk_v1

|高級講師

TA的文章

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