成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

[譯] 你真的知道 Angular 單向數(shù)據(jù)流嗎

fox_soyoung / 975人閱讀

摘要:所以,單向數(shù)據(jù)流的意思是指在變更檢測期間屬性綁定變更的架構(gòu)。相反,輸出綁定過程并沒有在變更檢測期間內(nèi)運(yùn)行,所以它沒有把單向數(shù)據(jù)流轉(zhuǎn)變?yōu)殡p向數(shù)據(jù)流。說的單向數(shù)據(jù)流說的是服務(wù)層,而不是視圖層嗷。

原文鏈接: Do you really know what unidirectional data flow means in?Angular
關(guān)于單向數(shù)據(jù)流,還可以參考這篇文章,且文中還有 youtube 視頻解析:Angular - What is Unidirectional Data Flow? Learn How the Angular Development Mode Works, why it"s important to use it and how to Troubleshoot it 。單向數(shù)據(jù)流一句話解釋就是:不要在 Angular 使用 Model 生成 View 這個過程中再去修改 Model。

大多數(shù)架構(gòu)模式是很難理解的,尤其是在相關(guān)資料很少時那就更加頭疼,比如 Angular 的單向數(shù)據(jù)流(unidirectional data flow)文檔資料就很少,即使官方文檔上,也僅僅在 表達(dá)式指南模板表達(dá)式 兩小塊中略有提及。我也很少在網(wǎng)上搜到比較好的解釋文章,所以寫此文是為了給 單向數(shù)據(jù)流(unidirectional data flow) 有個詳細(xì)的解釋。

雙向數(shù)據(jù)流和單向數(shù)據(jù)流

在討論 AngularJS 和 Angular 性能異同點(diǎn)時,就經(jīng)常會提到單向數(shù)據(jù)流模式,它也是 Angular 比 AngularJS 性能更快的原因所在。讓我們一起看看單向數(shù)據(jù)流究竟咋回事吧!(譯者注:AngularJS 指的是 1.X 版本,2+ 版本叫 Angular,使用 TypeScript 語言重寫了框架,包括架構(gòu)模式進(jìn)行了重新設(shè)計(jì),但兩者形似也神似。)

AngularJS 和 Angular 都是通過綁定來實(shí)現(xiàn)組件間數(shù)據(jù)通信,比如在 AngularJS 定義一個父組件 A

app.component("aComponent", {
  controller: class ParentComponent() {
    this.value = {name: "initial"};
  },
  template: `
    
  `
});
----------------
app.component("bComponent", {
    bindings: {
        obj: "="
    },

可以看到父組件 A 有個子組件 B,并且通過輸入綁定把父組件 Avalue 屬性值傳給子組件 Bobj 屬性:

這和 Angular 中組件間通信很類似了?。?/p>

@Component({
    template: `
        
    ...
export class AppComponent {
    value = {name: "initial"};
}
----------------
export class BComponent {
    @Input() obj;

第一件重要的事情是,Angular 和 AngularJS 都是在變更檢測(change detection)期間才去更新綁定值。所以,當(dāng) Angular 框架在為父組件 A 運(yùn)行變更檢測時,它會更新子組件 Bobj 屬性:

bComponentInstance.obj = aComponentInstance.value;

上面過程證明了單向數(shù)據(jù)流是數(shù)據(jù)從上往下流(譯者注:即數(shù)據(jù)從組件樹的父組件往子組件流),但是 AngularJS 卻不一樣,它可以允許在子組件中更新父組件的 value 屬性值

app.component("parentComponent", {
  controller: function ParentComponent($timeout) {    
    $timeout(()=>{
      console.log(this.value); // logs {name: "updated"}
    }, 3000)
  }
----------------
  
app.component("childComponent", {
    controller: function ChildComponent($timeout) {      
      $timeout(()=>{
        this.obj = { name: "updated" };  
      }, 2000)

上面代碼你可以看到兩個 timeout 回調(diào),第一個回調(diào)會更新子組件屬性,第二個回調(diào)會延遲第一個回調(diào)一秒,檢查父組件屬性是否被更新。如果你在 AngularJS 中運(yùn)行上面代碼你會發(fā)現(xiàn)父組件屬性已經(jīng)被更新了。讓我們一起看看究竟發(fā)生了什么?

當(dāng)?shù)谝粋€回調(diào)運(yùn)行時,子組件 Bobj 屬性被更新為 {name: "updated"},然后 AngularJS 運(yùn)行變更檢測。在變更檢測過程中,AngularJS 檢測到子組件綁定屬性的值發(fā)生改變,它會更新父組件 Avalue 屬性值。這是 AngularJS 變更檢測的內(nèi)置功能。如果你在 Angular 中做同樣的事情,它僅僅更新子組件的屬性值,但是子組件的改變不會冒泡到父組件,即 Angular 不會改變父組件的屬性值。這是升級版后的 Angular 變更檢測實(shí)現(xiàn),相較于 AngularJS 的最重大區(qū)別。然而,它卻困擾了我好久啊。

然而,Angular 也同樣可以通過子組件來更新父組件,這個機(jī)制就是輸出綁定(output binding)??梢韵襁@樣使用輸出綁定:

@Component({
    template: `
        

Hello {{value.name}}

... export class AppComponent { value = {name: "initial"}; constructor() { setTimeout(() => { console.log(this.value); // logs {name: "updated"} }, 3000); ---------------- @Component({...}) export class AComponent { @Output() updateObj = new EventEmitter(); constructor() { setTimeout(() => { this.updateObj.emit({name: "updated"}); }, 2000);

我承認(rèn)這個和從子組件直接更新還不太一樣,但是父組件值的確是更新了啊。很長一段時間我不明白為何這沒有被看做雙向數(shù)據(jù)綁定?畢竟,數(shù)據(jù)通信是在兩個方向進(jìn)行的。

直到有一晚我讀到了 Two Phases of Angular Applications?by?Victor Savkin,他解釋道(譯者注:為清晰理解,這個解釋不翻譯):

Angular 2 separates updating the application model and reflecting the state of the model in the view into two distinct phases.?The developer is responsible for updating the application model. Angular, by means of change detection, is responsible for reflecting the state of the model in the view.
(譯者注:意思就是 Angular 劃分了更新程序 model在前同步 model 和 view 在后兩個步驟,開發(fā)者只需要關(guān)注更新程序 model,同步 model 和 view 由 Angular 框架負(fù)責(zé),這個同步過程就是變更檢測,說白了就是更新 view。)
(譯者注:比如朋友圈點(diǎn)贊,首先就是手指觸發(fā)異步事件來更新程序 model,如在 Post 組件里給 likes 屬性加 1,然后在下一個 VM turn 時 Angular 會自動更新視圖中綁定的 likes 值, 即同步 model 和 view,點(diǎn)贊數(shù)就會從 0 變?yōu)?1。)

這讓我花費(fèi)好些天才明白,所謂的使用輸出綁定機(jī)制來更新父組件并不是在變更檢測中執(zhí)行的:

相反,它是在變更檢測前的更新程序 model 階段執(zhí)行的。所以,單向數(shù)據(jù)流的意思是指在變更檢測期間屬性綁定變更的架構(gòu)。在上面 Angular 代碼示例中,不像 AngularJS,在 Angular 變更檢測期間,并沒有代碼去讓子組件 AComponent 去更新父組件 AppComponent 的屬性。相反,輸出綁定過程并沒有在變更檢測期間內(nèi)運(yùn)行,所以它沒有把單向數(shù)據(jù)流轉(zhuǎn)變?yōu)殡p向數(shù)據(jù)流。

另外,盡管 Angular 沒有內(nèi)置機(jī)制可以使得在變更檢測期間去更新父組件,然而可以通過共享服務(wù)或廣播同步事件做到這一點(diǎn)。但是,由于 Angular 框架強(qiáng)迫單向數(shù)據(jù)流,所以這么做會導(dǎo)致ExpressionChangedAfterItHasBeenCheckedError 錯誤。想要了解導(dǎo)致這個錯誤的原因和解決方案可以參考 Everything you need to know about the ExpressionChangedAfterItHasBeenCheckedError。

視圖和服務(wù)層的單向數(shù)據(jù)流

你可能知道,大多數(shù) web 程序會設(shè)計(jì)成有兩層:視圖層和服務(wù)層。

Web 環(huán)境下視圖層主要通過 DOM 結(jié)構(gòu)向用戶展示相關(guān)程序數(shù)據(jù),在 Angular 中這一層是通過組件做的。服務(wù)層主要是處理和保存數(shù)據(jù),正如上圖中展示的,這一層又被切分為狀態(tài)管理和一些基礎(chǔ)部分,如 rest 服務(wù)或可重用工具服務(wù)(helpers)。

上文中提到的單向數(shù)據(jù)流指的是視圖層,因?yàn)樗f的是組件,而組件是用來構(gòu)建視圖的:

然而,在隨著實(shí)現(xiàn)了 redux 架構(gòu)的 ngrx 引入后,這又讓人迷惑了,因?yàn)?redux 文檔上有 這么一句(譯者注:為清晰理解,這句不翻譯):

Redux architecture revolves around a?strict unidirectional data flow.
This means that all data in an application follows the same lifecycle pattern, making the logic of your app more predictable and easier to understand…

實(shí)際上,這個嚴(yán)格單項(xiàng)數(shù)據(jù)流(strict unidirectional data flow)其實(shí)說的是服務(wù)層而不是視圖層。但我有時會搞混服務(wù)層和視圖層,會把 redux 的架構(gòu)模式與 Angular 的結(jié)構(gòu)模式聯(lián)系起來,當(dāng)然要避免搞混這兩層嗷。Redux 說的單向數(shù)據(jù)流說的是服務(wù)層,而不是視圖層嗷。 Redux 主要說的是狀態(tài)管理模塊,會把我們上文說的雙向數(shù)據(jù)流轉(zhuǎn)變?yōu)閱蜗驍?shù)據(jù)流。
把雙向數(shù)據(jù)流

轉(zhuǎn)換為單向數(shù)據(jù)流:

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

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

相關(guān)文章

  • [] 逐漸去掌握 React(作為一名 Angular 開發(fā)者)

    摘要:你是一個對感興趣的開發(fā)者嗎不用擔(dān)心,這真的不會讓你成為一個背叛者或其他什么,真的。事實(shí)上,這個想法并不是或獨(dú)創(chuàng)的它只是一種很棒的軟件開發(fā)實(shí)踐方式。把代碼分離到不同的文件里并不會自動導(dǎo)致關(guān)注點(diǎn)分離。 原文鏈接 : Getting to Grips with React (as an Angular developer)原文作者 : DAVE CEDDIA譯者 : 李林璞(web前端領(lǐng)域)...

    channg 評論0 收藏0
  • 前端優(yōu)化感想以及[]redux 教程 第一部分(共四部分

    摘要:自己英語一般,水平有限,獻(xiàn)上原文地址,還有我翻譯的中文地址,歡迎大家勘誤下面是自己的一點(diǎn)感想先說一下,我們知道,前端優(yōu)化有這么幾步,第一步首先呢我們知道,一個應(yīng)用要依賴好多條文件,而瀏覽器加載完一條,要執(zhí)行完這條才加載下一條,所以呢,就很慢 自己英語一般,水平有限,獻(xiàn)上原文地址,還有我翻譯的中文地址,歡迎大家勘誤 下面是自己的一點(diǎn)感想 先說一下webpack,我們知道,前端優(yōu)化有這么幾...

    snowell 評論0 收藏0
  • [] Controller間的數(shù)據(jù)共享?最佳實(shí)踐:使用Service

    摘要:共享數(shù)據(jù)的最佳策略是什么呢用一些變態(tài)的控制器繼承方案嗎當(dāng)然不是,最簡單容易的方式就是使用服務(wù)。概括創(chuàng)建一個服務(wù)去存放你的數(shù)據(jù),并給數(shù)據(jù)創(chuàng)建和的方法。 原文鏈接 : Sharing Data Between Controllers? Best Practice: Use a Service原文作者 : DAVE CEDDIA譯者 : 李林璞(web前端領(lǐng)域)譯者注:翻譯如有疏漏,歡迎指出...

    Salamander 評論0 收藏0
  • []Flux入門

    摘要:正式入坑我將按順序解釋概念,并且一個一個地構(gòu)建它們。視圖的和調(diào)度員本質(zhì)上是一個加入了額外規(guī)則的事件系統(tǒng)。它來廣播事件并注冊回調(diào)。這描述了我們的,我們稱之為。然后,會響應(yīng)已分派的操作這是處理調(diào)度回調(diào)的傳統(tǒng)方式。 原文地址:https://blog.andrewray.me/flu... ,作者:Andrew Ray TL;DR 當(dāng)我在努力學(xué)習(xí)Flux時,我希望有人告訴我:它并不簡單,也沒...

    Ashin 評論0 收藏0
  • 】每個JavaScript 開發(fā)者應(yīng)該了解的10個面試題

    摘要:避免脆弱的基類問題。紅牌警告沒有提到上述任何問題。單向數(shù)據(jù)流意味著模型是單一的事實(shí)來源。單向數(shù)據(jù)流是確定性的,而雙向綁定可能導(dǎo)致更難以遵循和理解的副作用。原文地址 1. 你能說出兩種對 JavaScript 應(yīng)用開發(fā)者而言的編程范式嗎? 希望聽到: 2. 什么是函數(shù)編程? 希望聽到: 3. 類繼承和原型繼承的不同? 希望聽到 4. 函數(shù)式編程和面向?qū)ο缶幊痰膬?yōu)缺點(diǎn)? ...

    mykurisu 評論0 收藏0

發(fā)表評論

0條評論

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