Angularjs進階筆記(2)-自定義指令中的數據綁定

来源:https://www.cnblogs.com/dashnowords/archive/2018/07/18/9332548.html
-Advertisement-
Play Games

有關自定義指令的scope參數,網上很多文章都在講這3種綁定方式實現的效果是什麼,但幾乎沒有人講到底怎麼使用,本篇希望聊聊 到底怎麼用 這個話題。 一. 自定義指令 自定義指令,是 用來實現組件化的方式,相比於 和`Vue`的組件化方式,它真的很複雜,自定義指令太重了,它暴露了太多可供定製的參數,以 ...


有關自定義指令的scope參數,網上很多文章都在講這3種綁定方式實現的效果是什麼,但幾乎沒有人講到底怎麼使用,本篇希望聊聊到底怎麼用這個話題。

一. 自定義指令

自定義指令,是Angularjs用來實現組件化的方式,相比於ReactVue的組件化方式,它真的很複雜,自定義指令太重了,它暴露了太多可供定製的參數,以至於普通的開發者完全不知道要用它來做什麼而將其束之高閣,畢竟一般的業務邏輯通過controller和service就已經可以完成了。

自定義指令在Angularjs項目中主要有兩大用途:

  • 1.封裝指定組件的DOM操作

    Angularjs期望的開發方式是將DOM的操作儘可能封裝在自定義指令中,這樣對於局部變數的操作會更容易加入到Angular自己的生命周期中。

  • 2.組件化

    Angularjs靠自定義指令實現組件化。諸如你在ReactVue中看到的類似於,這樣的自定義標簽,或是父級子級傳值所使用的prop,又或者是標記組件自身狀態的state,在Angularjs中全部都是通過自定義指令來實現的。

二. 數據綁定的形式

自定義指令在定義後,需要在html文件中編寫,最常用的方式是將其書寫為標簽屬性。當使用自定義指令時,常常需要將一個變數的值從controller傳遞至directive中,此時需要在scope屬性中進行變數綁定設置,Angularjs提供了3種不同的綁定方式(實際上也可以直接傳遞True),如下所示:

scope: {
   infiniteScroll: '=', // 將infiniteScroll同父級controller中的指定對象雙向綁定
   onSend: '&', // 從父級獲取一個變數的引用,常用作方法調用
   fromName: '@' // 從父級獲取值後便只在本地作用域生效
}

關於三種綁定方式使用的方法,網上可以搜到非常多的文章,本篇不再贅述,今天我們只來詳細看一下這幾種方式的使用場景和區別。

2.1 @綁定

@綁定可以轉移常量賦值的位置,常用於為自定義封裝組件暴露一個可設定常量參數的介面。這種綁定方式的意義,在於從自定義指令外部(一般是從html頁面上綁定一個常量或控制器中的變數)獲取一個局部變數的值。

實際場景:

例如我們封裝了一個分頁組件,其中指令局部作用域中的displayPaginationNums屬性用於決定分頁組件的頁碼欄顯示多少個按鈕,然後把剩餘的按鈕收起來並添加...按鈕,這是一個很常見的需求。

  • 不使用@綁定

    不使用@綁定,完全可以做到,只需要在link函數里,初始化為其賦值即可。

  link:function(scope, elements, attrs){
        scope.displayPaginationNums = 5;//用於決定分頁導航欄最多可顯示幾個數字
  },

使用這樣的方式,就可以,但我們預設了一個前提,那就是所有調用這個組件的人,都會瀏覽這個組件的源代碼。這其實是很不方便的,換位思考一下,你使用Angularjs的時候,會先去源碼里找一下對應的方法開頭都定義了哪些變數,哪些可以修改嗎?當然不會。

這個屬性在不同的項目中都會需要賦值,但需要動態去修改的場景其實並不多,所以我們需要將介面暴露至更高的開發層級,供調用者直接賦值。

  • 使用@綁定

    當使用@綁定後,我們實際上是面向調用者暴露了去設定重要參數的介面,使用起來更加方便。下麵的寫法讓開發者使用這個組件時,可以在代碼編寫時方便地傳入自己想要設定的值:

  //指令定義時
  scope:{
      displayPaginationNums:'@'
  },
  <!--指令調用時-->
  <div table-pagination
       display-pagination-nums="5">

面向對象程式設計原則中有一個重要的原則,叫做開放封閉原則,它的意思是說,你在程式設計中所書寫的代碼,應該對擴展開放,對修改封閉。簡單地說就是你所編寫的代碼成型以後,在後續的使用和功能擴展的時候,儘可能不需要再去改動代碼,而只需要通過編寫與擴展相關的代碼即可。

此處就是從封閉轉為開放的一個示例,雖然看起來很細小,但可以很明確地表達這個原則。

2.2 &綁定

&綁定用於傳遞父級函數的引用,用來調用父級控制器中定義的方法。如果只是以業務邏輯為模塊進行封裝,這種綁定方式可以幫我們避免一部分代碼重覆,如果是為通用框架編寫純組件,則可以為調用者提供自定義函數的介面。

實際場景:

比如我們在製作一個表格和分頁組件時,表格每一頁只顯示10條數據,分頁是後臺來完成的,那麼每一次點擊分頁組件上的頁碼按鈕時,我們都需要向後臺發送ajax請求來獲取新一頁的數據。那麼這個發送ajax請求的方法你會寫在哪裡呢?

不使用&綁定

  • 將方法寫在controller中

    優勢:這樣做的好處是如果以後我們需要增加一個輸入框來實現精確跳轉到哪一頁時,可以直接在模板中使用ng-change="sendAjax( )"來綁定這個方法,方便復用,擴展,甚至修改功能。

    劣勢:但這樣做的話,如果想在自定義指令中就無法直接調用這個方法,常見的處理策略是在自定義指令中使用scope.$emit( )將一個自定義事件發送至父級controller,在父級controller中使用$scope.$on( )來監聽這個自定義事件,併在回調中執行$scope.sendAjax( )這個方法。

  • 將方法寫在指令的link函數中

    優勢:可以將一些不需要用戶感知的函數封裝起來,例如數據發送前的校驗,或是響應數據的結構重組等,提高業務邏輯相關的代碼在controller中的比重,減小controller的體積。

    劣勢:當其他組件想要使用這個方法時會很困難,Angularjs並沒有提供一種跨directive調用方法的機制。

    實際上在開發過程中,不熟悉&綁定的開發者在使用自定義指令時,幾乎都會選擇將方法寫在controller中並通過消息機制來觸發這個函數(也就是上文中第一個方法),他們希望指令所封裝的組件是純粹的,換句話說,它是可復用且與業務邏輯剝離的。

使用&綁定

  • 對於業務邏輯開發而言

    簡潔且容易使用,組件可直接調用controller中的業務邏輯代碼,避免了當自定義事件過多時造成的controller中充滿了事件監聽的回調方法的問題,使用方法如下:

    //主模板中
    <div change-page="sendAjax"></div>
    //指令定義中
    ...
    template:'<div ng-click="changePage()"></div>'
    scope:{
        changePage: '&'
    },
    ...
  • 對於模塊封裝而言

    從上面的示例就可以看出,自定義指令中實際執行的changePage( )方法,是用戶在使用這個組件時編寫在controller之中的sendAjax( )這個方法,當我們需要封裝一個供其他開發者調用的組件時(往往是在編寫一個組件庫),這種結構是在angular中最自然的實現方式。

當你希望給一個自定義指令暴露越來越多個性化定製介面時,它很可能變得臃腫,甚至一無是處。

&綁定意義,在於將業務邏輯從組件中剝離出來,但過多的可定製性又會給開發者帶來額外的問題,你會發現,僅僅是簡單地使用一個下拉框或是勾選框之類的簡單組件時,就需要傳入一大堆自定屬性,而這本該是在交互設計標準中確定好並編寫在項目中的指定位置的。自定義指令的可定製性越高,html模板的體積就會越大,controller中的代碼量也會隨之增大,帶來的直接問題就是:開發很方便,維護很痛苦。

2.3 =綁定

=綁定是3中綁定形式中最常用的一種,常用於將用於渲染的數組或對象傳入自定義指令中。這樣做可以將業務邏輯分塊,使得代碼結構更具有層次性,降低維護難度。

實際場景:

一個表格組件,需要通過ajax請求從後臺獲取100條用於展示的數據,這些數據可能需要排序,過濾,分頁等操作,首先應該明確的是,即時這些代碼全部寫在controller中,程式也是可以運行的,只是當你在其他場合需要復用時,就需要複製粘貼很多代碼。那麼該如何來設計這樣一個功能並提取公用組件呢?排序過濾分頁都是表格組件的通用動作,也就是說與數據對象本身的結構並沒有太大關係,對於一個通用型表格控制項來說,我們唯一必須要傳入的只有一項——數據源,且它是有可能會隨著用戶操作而發生變化的。

推薦的技術方案為:

  • service : 封裝$http操作,信息提示,及容錯處理
  • controller : 調用service暴露的方法從後臺獲取數據,並賦值給指定變數
  • directive : 雙向數據綁定controller中的變數以獲取驅動表格渲染的數據,將排序,過濾,分頁的具體實現封裝在指令內部。

這樣的結構,使巨集觀業務邏輯前後臺信息交互組件通用功能分別在不同的模塊中實現,可以極大提高定位問題的速度。

=綁定的雙向數據綁定在使用中是存在一些方法問題的,詳情請參考《Angularjs1.X進階筆記(1)—兩種不同的雙向數據綁定》

三. 自定義指令的實用意義

  • =綁定—— 常用於傳遞從後臺獲取的用於驅動純組件的源數據。

  • @綁定—— 為自定義指令中傳遞可配置的常量參數提供設置介面。

  • &綁定—— 為自定義指令中傳遞自定義方法提供介面。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近公司做的項目需要向國外推廣,因此app需要添加相應的語言設置,為此整理記錄下多語言設置的過程。如有不對的地方,歡迎各位大神指正。下麵就詳細介紹下設置的過程: 1、基本設置 第一步:首先在 項目工程-PTROJECT-Info中添加需要支持的語言 如上點擊“+”號會彈出提供的語言列表,我們選擇項目 ...
  • 一,在模塊build.gradle中添加webSocket的依賴包 二,連接webSocket 三、添加內部類,實現回調監聽 ...
  • 一,效果圖。 二,代碼。 ...
  • 1 單頁面應用程式 Single Page Application (SPA) 從字面意義來看就是一個網站就一個頁面,如: coding 網易雲音樂 極致的用戶體驗,就像nativeapp一樣 優點: 具有桌面應用的即時性、網站的可移植性和可訪問性。 用戶體驗好、快,內容的改變不需要重新載入整個頁面 ...
  • 隨著移動時代的崛起,據統計,我國目前有10億手機用戶通過手機訪問網站,那麼我們做優化的當然也不能放掉移動端這一塊肥肉了,之前我們做網站包括優化網站都是PC端的網站優化,忽略的移動端。 到目前位置許多行業都很少有專門針對移動端的網站。 現在有些網站建設公司在做網站的時候喜歡向客戶推薦移動、pc兩種站點 ...
  • 深入淺出padding padding是CSS盒子模型的一部分,代表盒子模型的內邊距。 用法 padding屬性有四個值,分別代表上、右、下、左的內邊距。 此時, 的內邊距為: 上內邊距:10px 右內邊距:5px 下內邊距:15px 左內邊距:20px 簡寫 padding屬性的值可以簡寫,按照值 ...
  • 來源:https://segmentfault.com/a/1190000015652209 本系列文章分為三個部分: 第一部分是 SVG 基礎。 主要講 SVG 的一些基礎知識,包括 SVG 基本元素,畫布和視窗等。 第二部分是 SVG 的坐標系統。主要會講繪圖坐標系, viewBox 以及pre ...
  • NPM 學習筆記整理 閱讀 550,2017年06月04日 發佈,來源:blog.ihoey.com 什麼是 NPM npm 之於 Node ,就像 pip 之於 Python , gem 之於 Ruby , pear 之於 PHP 。 npm 是 Node 官方提供的包管理工具,他已經成了 Nod ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...