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

資訊專欄INFORMATION COLUMN

[Tips on Ember 2] UI 布局與應(yīng)用狀態(tài)的關(guān)系處理

wayneli / 732人閱讀

摘要:如果說傳統(tǒng)的前端開發(fā)是以頁面為中心來入手的話,那么現(xiàn)代的應(yīng)用開發(fā)就是以狀態(tài)為中心來著手設(shè)計和開發(fā)的。初步分析路由是怎么管理狀態(tài)的復(fù)雜的話題簡單說在中,應(yīng)用的每一個可能的狀態(tài)都是通過體現(xiàn)的。

引子

SPA(單頁面應(yīng)用)的核心是什么?

自該類型應(yīng)用誕生以來我最多思考的問題就是這個。現(xiàn)在前端 SPA 框架滿天飛,許多不是框架的也被稱作框架,究竟有什么代表性的層(layer)能讓一個系統(tǒng)稱得上是框架?

我的答案是路由,而路由的本質(zhì)就是一個狀態(tài)管理器。沒有路由機(jī)制的系統(tǒng)不能稱之為框架,而路由機(jī)制做得不好的框架也算不上好框架(但可以算是好的工具集合,比如 Angular——詳見我在 Ruby China 上曾經(jīng)吐過的槽)。

為什么這么說呢?我們都知道 HTML 是無狀態(tài)的(stateless),做一堆 HTML 頁面拼在一起那不叫“應(yīng)用”,頂多稱之為“內(nèi)容系統(tǒng)”;在以前,HTML 網(wǎng)站上的狀態(tài)管理是由后端的 Session 加前端的 Cookies 協(xié)作完成的,到了 SPA 的時代 Session 不是必須的了(盡管傳統(tǒng)的 Session 機(jī)制也是可用的),UI 上的狀態(tài)轉(zhuǎn)移到了前端由 JavaScript 完全管控(由于 SPA 前后分離的特點),所以前端工程師擔(dān)負(fù)起了更多的業(yè)務(wù)邏輯職責(zé),相應(yīng)的整個技術(shù)鏈上也必須有一個可靠的環(huán)節(jié)來幫助他們做狀態(tài)管理這件事情。

在前端框架的發(fā)展過程中路由的誕生是水到渠成的(基于一些新技術(shù)的成熟,比如 HTML5 的History API 等等),但是應(yīng)用開發(fā)工程師對于路由的理解和重視卻還遠(yuǎn)遠(yuǎn)不夠。如果說傳統(tǒng)的前端開發(fā)是以頁面為中心來入手的話,那么現(xiàn)代的 SPA 應(yīng)用開發(fā)就是以狀態(tài)為中心來著手設(shè)計和開發(fā)的。

Ember 就是一款非常重視路由組件的 SPA 框架,本文借由一個實現(xiàn) UI 布局的例子來談?wù)?UI 編程與路由的關(guān)系,盡管這只是涉及到路由特性的一部分卻也足夠說明一些問題了。希望這個例子能讓更多前端工程師認(rèn)識和理解路由的重要性,從而更好的設(shè)計與實現(xiàn) SPA 應(yīng)用的各種功能場景。

場景描述

多數(shù)應(yīng)用都有如下所述的 UI 設(shè)計:

多數(shù)視圖在一個通用的布局內(nèi)呈現(xiàn),比如典型的 Header + Main 的布局

個別視圖需要一個特定的布局,比如登錄和注冊頁面不需要 Header 等等

對于這些場景來說,那些重復(fù)的 HTML 結(jié)構(gòu)(如 Header 和 Footer)肯定需要某種方式的抽象使得它們可以復(fù)用或者指定渲染還是不渲染。后端渲染技術(shù)使用了一些機(jī)制(如 helpers 等) 來幫助開發(fā)者在視圖層實現(xiàn)這些邏輯,等到返回給瀏覽器的時候已經(jīng)是完整的 HTML 了(當(dāng)然也有 Turbolinks 這樣融合了部分前端路由特性的新技術(shù),本文不做進(jìn)一步描述),這顯然是不適合前端應(yīng)用的場景的,因為對于 SPA 應(yīng)用來說用戶更換 URLs 時需要在瀏覽器端即時拼裝最終的完整視圖,并不存在“預(yù)先渲染好的頁面一起交付過來”這么一說。我們需要先思考一下高層設(shè)計,看看有什么機(jī)制可以利用的。

初步分析

路由是怎么管理狀態(tài)的?復(fù)雜的話題簡單說:

In Ember.js, each of the possible states in your application is represented by a URL.
在 Ember.js 中,應(yīng)用的每一個可能的狀態(tài)都是通過 URL 體現(xiàn)的。

這是官方文檔里所總結(jié)的,我來試著舉例表述一下:

假設(shè)當(dāng)前有如下路由定義:

let Router = Ember.Router.extend()

Router.map(function() {
    this.route("dashboard", { path: "/dashboard" })
    this.route("signin", { path: "/signin" })
})

于是,當(dāng)用戶——

進(jìn)入 /dashboard URL 的時候,對應(yīng)的 dashboard 路由開始接管應(yīng)用的當(dāng)前狀態(tài)

進(jìn)入 /signin URL 的時候,對應(yīng)的 signin 路由開始接管應(yīng)用的當(dāng)前狀態(tài)

但更重要的是:所有的路由都有一個共有的頂級路由——application 路由,其重要性主要體現(xiàn)在:

它是唯一一個靠譜的可以用來管理全局范圍狀態(tài)的路由

它為所有子路由的視圖渲染提供了模板的入口(outlet)

接著問題來了:如果說狀態(tài)通過 URL 來體現(xiàn),那么 UI 布局的不同如何體現(xiàn)呢?比如:

進(jìn)入 /dashboard URL 的時候,我們需要 Header + Main 的布局

進(jìn)入 /signin URL 的時候,我們不需要 Header

無論何種情形,application 路由在其中的作用……?

第一次嘗試

因為每一個路由都會渲染自己的模版,我們可以做一個最簡單的嘗試:

{{!app/pods/application/template.hbs}}
{{outlet}}
{{!app/pods/dashboard/template.hbs}}
...
... {{outlet}}
{{!app/pods/signin/template.hbs}}
... {{outlet}}

雖然這么做可以奏效,然而問題也是顯而易見的:如果出現(xiàn)多個和 dashboard 一樣的布局結(jié)構(gòu),我們將不得不多次重復(fù)

;曾經(jīng) Ember 有 {{partial}} 這樣的 helper 來做模版片段復(fù)用,但是第一,以后沒有 {{partial}} 了,二來用 {{partial}} 做布局是錯誤的選擇。

問題分析

如果我們可以把問題場景簡化為只有一種可能,例如“所有的視圖都用 Header + Main 的布局”,那么解決方案可以簡化為:

{{!app/pods/application/template.hbs}}
...
{{outlet}}
...
{{!app/pods/dashboard/template.hbs}}
...
{{outlet}}
{{!app/pods/signin/template.hbs}}
...
{{outlet}}

那么再次恢復(fù)原來的場景要求,問題變成了:“進(jìn)入 /signin 之后,如何隱藏 application 模版里的

?

第二次嘗試

隱藏模版里的片段,最簡單的方法可以這么做:

{{!app/pods/application/template.hbs}}
{{#if showNavbar}}
...
{{/if}}
{{outlet}}

我們知道模版內(nèi)可訪問的變量可以通過控制器來設(shè)置,但此時我不打算創(chuàng)建 ApplicationController,因為路由里有一個 setupController 的鉤子方法能幫我們設(shè)置控制器的(更重要的原因是很快 Routable Components 將取代現(xiàn)在的 route + controller + template 的分層體系,所以從現(xiàn)在開始最好盡可能少的依賴 controller),試試看:

// app/pods/application/route.js
export default Ember.Route.extend({
    setupController(controller) {
        this._super(...arguments)
        controller.set("showNavbar", true)
    }),
})

現(xiàn)在所有的狀態(tài)都會顯示 header 部分了,那怎么讓 /signin 不顯示呢?或許這樣……?

// app/pods/signin/route.js
export default Ember.Route.extend({
    setupController() {
        this._super(...arguments)
        this.controllerFor("application").set("showNavbar", false)
    }),
})

以下是測試結(jié)果(這里建議先寫 Acceptance Test,省時間且不易錯漏),在每次刷新頁面后:

從... 到... 結(jié)果
/ /dashboard 成功
/dashboard / 成功
/ /signin 成功
/signin / 失敗
/dashboard /signin 成功
/signin /dashboard 失敗
/signin /dashboard 失敗
/dashboard /signin 失敗

我們在測試中增加了 /dashboard 的訪問,但是我們并沒有定義位于 DashboardRoute 里的 setupController 鉤子,這是因為我們期望 /dashboard 能夠繼承 / 的狀態(tài),否則所有的路由都要設(shè)置類似的 setupController 會把人累死,然而測試結(jié)果可能會讓初學(xué)者覺得摸不著頭腦,我們試著分析一下好了:

//dashboard 都需要 showNavbar === true,所以正反都可以;

當(dāng)自 /signin 刷新頁面的時候,先執(zhí)行了 ApplicationRoute 然后才是 SigninRoute,等到進(jìn)入 / 的時候,setupController 不會再次執(zhí)行的;

同上;

同上。

問題分析

這里最明顯的問題就是 ApplicationRoute#setupController 這個鉤子方法是不可靠的,你只能保證它的第一次運(yùn)行,一旦變成了在路由之間來回跳轉(zhuǎn)就無效了。

實際上,setupController 的作用是將 model 鉤子返回的結(jié)果綁定在對應(yīng)的控制器上的,你可以擴(kuò)展這個邏輯但也僅限于數(shù)據(jù)層面的設(shè)置。只有當(dāng)調(diào)用了 route#render() 且返回了與之前不同的 model 時 setupController 才會再次被調(diào)用。

于是問題又變成了:有哪一個鉤子方法能保證在路由發(fā)生變化的時候都可用?

路由的生命周期

這是一個非常重要但又很無趣的主題,我不想在這里重復(fù)那些可以通過閱讀文檔和親測就可以得出的答案,不過我可以給出一份測試路由生命周期的完整代碼片段:

https://gist.github.com/nightire/f766850fd225a9ec4aa2

把它們放進(jìn)你的路由當(dāng)中然后仔細(xì)觀察吧。順便給你一些經(jīng)驗之談:

這個測試不要錯過 ApplicationRoute,因為它是最特殊的一個

其他的路由至少要同時測試兩個,比如 IndexRouteTestRoute

不要只測試頁面刷新后的生命周期,還要嘗試各種路由之間的相互過渡

測試完之后,你就會對整個路由系統(tǒng)有一個非常全面的了解了,這些體驗會帶給你一個重要的技能,即是在將來你可以很容易的決斷出實現(xiàn)一個功能應(yīng)該從哪里入手。對于我們這個例子來說,比較重要的結(jié)論如下:

ApplicationRoute 是所有路由的共同先祖,當(dāng)你第一次進(jìn)入應(yīng)用程序——無論是從 / 進(jìn)入還是從 /some/complicated/state 進(jìn)入——ApplicationRoute 都是第一個實例化的路由,并且它 activated 就不會 deactivated 了(除非你手動刷新瀏覽器)。因此我們可以把 ApplicationRoute 作為一個特殊的永遠(yuǎn)激活的路由

如果你有應(yīng)用邏輯依存于 ApplicationRoute#setupController,那么第一次進(jìn)入就是唯一靠譜的機(jī)會——你不能指望這個鉤子會在路由來回切換的時候觸發(fā)

但是其他路由上的 #setupController 鉤子是會在每次過渡進(jìn)來的時候重新執(zhí)行的

第三次嘗試

基于以上分析,我們可以調(diào)整我們的代碼了:

// app/pods/application/route.js
export default Ember.Route.extend()
// app/pods/index/route.js and app/pods/dashboard/route.js
export default Ember.Route.extend({
    setupController() {
        this._super(...arguments)
        this.controllerFor("application").set("showNavbar", true)
    },
})
// app/pods/signin/route.js
export default Ember.Route.extend({
    setupController() {
        this._super(...arguments)
        this.controllerFor("application").set("showNavbar", false)
    },
})

我們把 ApplicationRoute#setupController 里的邏輯轉(zhuǎn)移到了 IndexRoute#setupController 里去,就是因為當(dāng)你訪問 / 的時候,ApplicationRoute#setupController 只會觸發(fā)一次(第一次刷新的時候),而 IndexRoute#setupController 則可以保證每次都觸發(fā)。現(xiàn)在,我們設(shè)想的場景可以實現(xiàn)了。

這個設(shè)定一開始看起來非常古怪,很多初學(xué)者都在這里被搞暈掉:“為什么要有 IndexRoute?為什么不直接用 ApplicationRoute?”

抽象路由

當(dāng)我們剛開始接觸前端的路由機(jī)制時,我們很容易把 ApplicationRoute/ 關(guān)聯(lián)起來,可實際上真正和 / 關(guān)聯(lián)的是 IndexRoute。如果你沒有自行創(chuàng)建 IndexRoute,Ember 會幫你創(chuàng)建一個,但不管怎樣 IndexRoute 都是必不可少的。

那么 ApplicationRoute 到底扮演著一個什么樣的角色呢?

先記住這個結(jié)論:在路由系統(tǒng)中,路由樹中任何一個當(dāng)前激活的路徑都會至少包括兩個路由節(jié)點,并且其中一個必然是 ApplicationRoute這也正是 ApplicationRoute 永遠(yuǎn)處于 activated 而永遠(yuǎn)不會 deactivate 的原因所在。

舉幾個例子:

當(dāng)訪問 "/" 時,路由樹中當(dāng)前激活的路徑為:application => index

當(dāng)訪問 "/users/new" 時,路由樹中當(dāng)前激活的路徑為:application => users => new

當(dāng)訪問 "/posts/1/comments/1" 時,路由樹中當(dāng)前激活的路徑為:application => post => index => comment => index,也可能是:application => posts => show => comments => show ——取決于你的路由規(guī)則的寫法

等等……

Ember 并沒有為這個特殊的 |41b8a0714e572ed059c0e52d0e3c676c91| 做一個明確的定義(但是|41b8a0714e572ed059c0e52d0e3c676c92|),不過在其他類似的路由系統(tǒng)里我們可以找到等價物——比如來自 |41b8a0714e572ed059c0e52d0e3c676c93|(Angular 生態(tài)圈里最優(yōu)秀的路由系統(tǒng))里的抽象路由(Abstract Route)。

Ember 的 ApplicationRoute 和 ui.router 的抽象路由非常相似,它們的共性包括:

都能夠擁有子路由

自身都不能被直接激活(不能位于路由樹中當(dāng)前激活路徑的頂點)

不能直接過渡,也就是 transition to;Ember 里會等價于過渡到 IndexRoute,ui.router 則會拋出異常

都有對應(yīng)的模版、控制器、數(shù)據(jù)入口、生命周期鉤子等等

當(dāng)其下的任意子路由被激活,作為父節(jié)點的抽象路由都會被激活

當(dāng)然,它們也有不同,比如說:你可以在 ui.router 的路由樹中任意定義抽象路由,不受數(shù)量和節(jié)點深度的限制,只要保證抽象路由不會位于某條路徑的頂點就是了;而 Ember Router 只有一個抽象路由(而且并沒有明確的定義語法,只是行為類似——典型的鴨子類型設(shè)計嘛)且只能是 ApplicationRoute,你可以手動創(chuàng)建別的路由來模擬,但是 Ember Router 不會阻止你過渡到這些路由,不像 ui.router 會拋出異常(這一點很容易讓初學(xué)者碰壁)

實際上當(dāng)你對 Ember Router 的理解日漸深入之后你會發(fā)現(xiàn)所有的嵌套路由(包括頂層路由)都是抽象路由,因為它們都會隱式的創(chuàng)建對應(yīng)的 |41b8a0714e572ed059c0e52d0e3c676c98| 作為該路徑的頂節(jié)點,訪問它們就等于訪問它們的 |41b8a0714e572ed059c0e52d0e3c676c99|。我認(rèn)為 Ember Router 的這個設(shè)計與 ui.router 相比有利有弊:

利:設(shè)計精巧簡單,可以避免大量的 boilerplate 代碼,路由的定義相對清晰簡潔

弊:對于初學(xué)者來說,由于不存在抽象路由的概念,很難深刻理解父子節(jié)點,特別是隱式 IndexRoute 的存在價值

這個方案足夠完美了嗎?

不,還差一些。試想:當(dāng)我們需要很多路由來組織應(yīng)用程序的結(jié)構(gòu)時,類似的 #setupController 豈不是要重復(fù)定義很多次?如何抽象這一邏輯讓其變得易于復(fù)用和維護(hù)?

Thinking in Angular way(w/ ui.router)

在開發(fā) Angular 應(yīng)用的時候,類似場景的路由定義一般是這樣的:

                   +----> layoutOne(with header) +----> childrenRoutes(like dashboard, etc.)       
                   |
                   |
application(root) -|
                   |
                   |
                   +----> layoutTwo(without header) +----> childrenRoutes(like signin, etc.)

我們用 Ember Router 也可以模擬這樣的路由定義,實現(xiàn)同樣的結(jié)果,代碼類似:

// app/router.js
let Router = Ember.Router.extend({
  location: config.locationType,
})

Router.map(function() {
    // provide layout w/ 
this.route("layoutOne", { path: "/" }, function() { this.route("dashboard", { resetNamespace: true }) // ... }) // provide layout w/o
this.route("layoutTwo", { path: "/" }, function() { this.route("signin", { resetNamespace: true }) // ... }) })

但是個人非常不喜歡也不推崇這么做,原因是:

這樣的路由定義寫多了會很惡心

為了避免類似 /layoutOne/dashboard 這樣的 URLs,不得不重復(fù)設(shè)定 path: "/" 來覆蓋

ui.router 解決此問題依靠的是 url pattern inheritence,由于每一個路由的定義都必須指明 url 屬性,所以也就習(xí)慣了

為了避免類似 layoutTwo.signin 這樣的路由名字,不得不重復(fù)設(shè)定 resetNamespace: true

ui.router 解決此問題依靠的是路由定義里的 parent 屬性,所以子路由是可以分開定義的,不用嵌套也就無需 resetNamespace

對比兩家的路由定義語法,各有優(yōu)缺點吧,但是 Ember Router 向來都是以簡明扼要著稱的,真心不喜歡為了這個小小需求而把路由定義寫得一塌糊涂

另外這樣的路由設(shè)計還會導(dǎo)致 application 這個模版變成一個廢物,除了 {{outlet}} 它啥也做不成,生成的 DOM Tree 里平白多一個標(biāo)簽看的人直惡心~

Thinking in Ember way

既然問題的本質(zhì)是 #setupController 鉤子需要重復(fù)定義,那么有沒有 Ember 風(fēng)格辦法來解決這一問題呢?

首先我們來考量一下 Mixin,你可以這么做:

// app/mixins/show-navbar.js
export default Ember.Mixin.create({
    setupController() {
        this._super(...arguments)
        this.controllerFor("application").set("showNavbar", true)
    },
})

// app/mixins/hide-navbar.js
export default Ember.Mixin.create({
    setupController() {
        this._super(...arguments)
        this.controllerFor("application").set("showNavbar", false)
    },
})
// app/pods/index/route.js and app/pods/dashboard/route.js
import ShowNavbarMixin from "../../mixins/show-navbar"

export default Ember.Route.extend(ShowNavbarMixin, {
    // ...
})

// app/pods/signin/route.js
import HideNavbarMixin from "../../mixins/hide-navbar"

export default Ember.Route.extend(HideNavbarMixin, {
    // ...
})

這么做倒也不是不行,但是——明顯很蠢嘛——這和抽取兩個方法然后到處調(diào)用沒有什么本質(zhì)的區(qū)別,看起來我們需要的是某種程度上的繼承與重寫才對:

// somewhere in app/app.js
Ember.Route.reopen({
    // show navbar by default, can be overwriten when define a specific route
    withLayout: true,

    setupController() {
        this._super(...arguments)
        this.controllerFor("application").set(
            "showNavbar", this.get("withLayout")
        )
    },
})
// app/pods/index/route.js and app/pods/dashboard/route.js
// Do nothing if showNavbar: true is expected

// app/pods/signin/route.js
export default Ember.Route.extend({
    withLayout: false,
})

這樣就行了,不需要額外的路由體系設(shè)計,就用 Ember 的對象系統(tǒng)便足夠完美。本文所描述的這個例子其實非常簡單,我相信略有 Ember 經(jīng)驗的開發(fā)者都能做出來,但是我的重點不在于這個例子,而在于對路由系統(tǒng)的一些闡述和理解。這個例子來源自真實的工作,為了給同事解釋清楚最初的方案為什么不行著實費(fèi)了我好大功夫,于是我把整個梳理過程記錄下來,希望對初學(xué)者——特別是對 SPA 的核心尚未了解的初學(xué)者能有所助益吧。

基于事件的解決方案

這個問題其實還有多種解法,基于事件響應(yīng)的解法我就在現(xiàn)實里演示了兩種,不過相比于上面的最終方案,它們還是略微糙了些。在這里我寫其中一種比較少見的,里面涉及到一些 Ember 的內(nèi)部機(jī)制,權(quán)當(dāng)是一個借鑒吧,思路我就不多解釋了。

// app/mixins/hide-navbar.js
export default Ember.Mixin.create({
    hideNavbar: function() {
        this.set("showNavbar", false)
    }.on("init"),
})
// app/router.js
let Router = Ember.Router.extend({
    location: config.locationType,

    didTransition() {
        this._super(...arguments)

        let currentRoute = this.get("container")
        .lookup(`route:${this.get("currentRouteName")}`)

        this.get("container").lookup("controller:application").set(
            "showNavbar", _.isUndefined(currentRoute.get("showNavbar"))
        )
    }
})
// app/pods/signin/route.js
import HideNavbarMixin from "../../mixins/hide-navbar"

export default Ember.Route.extend(HideNavbarMixin, {
    // only use this mixin when you need to hide the Header
})

原文首發(fā)于 Ruby China 社區(qū),轉(zhuǎn)載請注明。

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/85962.html

相關(guān)文章

  • [Tips on Ember 2] Ember CLI 和 Sass (及其周邊) 協(xié)同工作

    摘要:今天這篇主要講講里關(guān)于樣式開發(fā)的一些前期準(zhǔn)備工作,主要是和??偟膩碚f就不要再用了,又大又笨而且連親爹都準(zhǔn)備放棄它了,未來將是小快靈組件協(xié)同工作的大趨勢,就是可以用來替代的組件庫。 今天這篇主要講講 Ember CLI 里關(guān)于樣式開發(fā)的一些前期準(zhǔn)備工作,主要是 Sass 和 Bootstrap。 Ember Addons 是尋找各種組件的絕佳場所,下文將要介紹的一些都可以在這里找到,沒事...

    ziwenxie 評論0 收藏0
  • [Tips on Ember 2] How components works when out of

    摘要:因為組件的存在范圍被限制在以內(nèi),這就是這種機(jī)制目前存在的意義所在。組件都是可以傳遞參數(shù)或外部作用域的,利用此機(jī)制進(jìn)行判斷來執(zhí)行可選行為,這是對用戶友好的舉措。 這一篇還是一個簡單的例子所引發(fā)的思考。 你看,如今的框架和庫,無論規(guī)模大小功能多少,它們在本質(zhì)上都朝著組件化的思路快速演進(jìn)著。Angular 有 directives,Angular 2應(yīng)該也還是這個叫法;Ember 從 Vie...

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

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

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

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

    Yu_Huang 評論0 收藏0
  • 【譯】JavaScript 框架探索變遷(上)

    摘要:正文在年,框架的選擇并不少。特別的,通過思考這些框架分別如何處理狀態(tài)變化是很有用的。本文探索以下的數(shù)據(jù)綁定,的臟檢查的虛擬以及它與不可變數(shù)據(jù)結(jié)構(gòu)之間的聯(lián)系。當(dāng)狀態(tài)產(chǎn)生變化時,只有真正需要更新的部分才會發(fā)生改變。 譯者言 近幾年可謂是 JavaScript 的大爆炸紀(jì)元,各種框架類庫層出不窮,它們給前端帶來一個又一個的新思想。從以前我們用的 jQuery 直接操作 DOM,到 Backb...

    Jaden 評論0 收藏0

發(fā)表評論

0條評論

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