1. 程式人生 > >Angular2中自定義元件實現雙向繫結

Angular2中自定義元件實現雙向繫結

    在Angular2中的資料流動是單向的,我們常見的雙向繫結的例子如下:
<input [(ngModel)]="value"/>

等價於

<input [ngModel]="value" (ngModelChange)="valueChange($event)"/>

    那麼我們如何實現自定義自己的元件,該元件也可以接受[(ngModel)]來實現雙向繫結呢?首先來看元件的定義程式碼:

@Component({
  selector: 'app-two-way',
  template: `<input [(ngModel)]="value">`,
  styleUrls: ['./two-way.component.css'],
  providers: [{
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => TwoWayComponent),
    multi: true,
  }],
})
export class TwoWayComponent implements ControlValueAccessor {
  private innerValue: any = '';
  private onTouchedCallback: () => void = noop;
  private onChangeCallback: (_: any) => void = noop;

  get value(): any {
    return this.innerValue;
  };

  set value(v: any) {
    if (v !== this.innerValue) {
      this.innerValue = v;
      this.onChangeCallback(v);
    }
  }

  writeValue(value: any): void {
    if (value !== this.innerValue) {
      this.innerValue = value;
    }
  }

  registerOnChange(fn: any): void {
    this.onChangeCallback = fn;
  }

  registerOnTouched(fn: any): void {
    this.onTouchedCallback = fn;
  }

}

    這樣在template中使用該元件的時候就可以類似於input標籤一樣可以接受ngModel和ngModelChange了。下面來解釋其中使用的東西:

  • NG_VALIDATORS:為form control提供ControlValueAccessor,所以我們的元件要實現ControlValueAccessor介面。
  • useExisting:避免出現多個provider
  • forwardRef:在依賴注入中,每個元件都需要有個與其關聯的token,可是在provider註冊的時候,我們的元件還沒有初始化。所以需要使用forwardRef來告知provider構造器這些,使其可以等元件初始化。

接下來就是實現ControlValueAccessor介面,主要的函式是:

  • writeValue:將外部傳遞進來的值寫到模板中
  • registerOnChange:該函式接收一個回撥函式,用於在資料發生變化時告知外面的世界。

    在元件定義中,我們定義了onTouchedCallback和onChangeCallback,但是方法都是沒有任何實現的,這個定義時必須的。而且這兩個方法的真正實現都會在元件初始化時由Angular自己來提供。所以我們不必擔心這兩個方法沒有任何實現的。

相關推薦

Angular2定義元件實現雙向

    在Angular2中的資料流動是單向的,我們常見的雙向繫結的例子如下:<input [(ngModel)]="value"/>等價於<input [ngModel]="value" (ngModelChange)="valueChange($even

Android DataBinding (五) 定義 View 的雙向

前言 自定義 View 的時候如果用到非系統定義的屬性的時候,如果要實現雙向繫結,不是用了 @= 就行的,自定義 View 中還需要一些設定。 下面通過一個例子來說明自定義 View 的雙向繫結的實現。 例子要求: 1. 通過 RadioButton

vue定義元件實現v-model雙向

vue中父子元件通訊,都是單項的,直接在子元件中修改prop傳的值vue也會給出一個警告,接下來就用一個小列子一步一步實現了vue自定義的元件實現v-model雙向繫結,父元件值變了子元件也會跟著變,子元件中傳過來的值變了,父元件值也會跟著變化。如有錯誤的地方歡迎評論指出 父級元件

如何在Vue2實現元件props雙向

Vue學習筆記-3 前言 Vue 2.x相比較Vue 1.x而言,升級變化除了實現了Virtual-Dom以外,給使用者最大不適就是移除的元件的props的雙向繫結功能。 以往在Vue1.x中利用props的twoWay和.sync繫結修飾符就可以實現props的雙向繫結功能,但是在Vue2中徹底廢棄了此功能

iOS定義View實現layoutSubviews佈局子控制元件

iOS開發中,- (void)layoutSubviews{}方法及相關方法注意點!! ==== ```objectivec - (void)creatAutoLayoutUSE { // 一、layout相關方法 } ``` - (void)layoutSubviews

Vue 定義元件(包含例項)

Vue 支援自定義元件,方便我們在開發過程中根據自己的專案自定義元件。 定義 主要是通過 Vue.component( ) 來完成。新建一個 alert.js 檔案: // 自定義一個 alert 元件 Vue.component('alert', { template: '&

Vue定義元件實現按鈕許可權功能

在這之前請看我上一篇部落格https://blog.csdn.net/qq_41594146/article/details/83381964,這裡有思路和資料庫設定,之前做的是沒有元件化,也就是單純的v-for迴圈直接顯示,剛剛寫了按鈕許可權的元件,現在貼上程式碼\ var myBu

使用vue定義元件實現樹形列表

最近公司做新專案用的是vue,有一個功能做一個樹形列表由於之前一直用的是jquery操作dom,剛接觸vue走了不少彎路,特意寫部落格記錄一下 一、js自定義一個元件       <script type="text/template" id

微信小程式定義元件實現地址單級連續選擇(拼多多APP地址選擇樣式)

最終效果在 首先在page資料夾下建立components資料夾,在components資料夾下建立region-picker的資料夾,然後在region-picker資料夾下建立Component名稱為region-picker。 region-picke

vue定義元件(外掛)

在vue專案中,可以自定義元件像vue-resource一樣使用Vue.use()方法來使用,具體實現方法: 1、首先建一個自定義元件的資料夾,比如叫loading,裡面有一個index.js,還有一個自定義元件loading.vue,在這個loading.v

Vue使用.sync 實現父子元件雙向資料

1.前言 最近在vue 專案中有一個需求, 就是我需要根據不同的型別在頁面中放不同的元件, 元件需要跟當前頁面的資料進行雙向繫結,如果都寫在同一個頁面 程式碼會顯得比較多,畢竟我當前頁面已經7-800行程式碼了 所以我需要把一些元素定義成元件 ,封裝起來,所以就會遇到 資料的傳

定義元件實現底部彈出選單

1.效果圖 點選客服按鈕,從底部彈出選單欄 點選微信線上客服,可以喚起微信客服 2.為什麼要自己寫選單欄? 微信原生的選單欄不支援直接喚起微信客服唄,難受== 不想說話了,貼程式碼 3.程式碼段 定義元件

Android定義MultipartEntity實現檔案上傳以及使用Volley庫實現檔案上傳

最近在參加CSDN部落格之星,希望大家給投一票,謝謝啦~                       點這裡投我一票吧~前言在開發當中,我們常常需要實現檔案上傳,比較常見的就是圖片上傳,比如修改個頭像什麼的。但是這個功能在Android和iOS中都沒有預設的實現類,對於And

使用微信小程式定義元件實現的tabs選項卡功能

一個自定義元件由 json wxml wxss js 4個檔案組成。要編寫一個自定義元件,首先需要在 json 檔案中進行自定義元件宣告(將 component 欄位設為 true 可這一組檔案設為自定義元件) components/navigator/i

安卓定義LinerLayout實現listview的效果

public class LinearLayoutForNet extends LinearLayout { private NetBasePaiAdapter adapter; public LinearLayoutForNet(Context context)

vue2.0在頁面定義元件模組,以及頁面與元件之間的資料傳遞

1.在頁面上引入寫好的元件import UpdataPassword from './updataPassWord'       //updataPassWord為元件的name2.註冊元件components:{               //註冊元件  UpdataPa

java定義實現synchronized功能

public class Test {private static long count = 0;private Lock lock = new Lock();private int m = 0;private int a = 0;private int b = 0;pub

JavaScriptMVVM框架是如何實現雙向

我們先來看一個簡單的實現思路。 // 定義一個變化通知的回撥 var callback = function(newVal, oldVal) { alert(newVal + '---' + oldVal) } // 定義一個普通物件作為資料模型

vue父子元件通過sync實現雙向

背景: 日常開發時,我們總會遇到需要父子元件雙向繫結的問題,但是考慮到元件的可維護性,vue中是不允許子元件改變父元件傳的props值的。那麼同時,vue中也提供了一種解決方案.sync修飾符。在此之前,希望你已經知道了vue中是如何通過事件的方式實現子元件修改父元件的da

vuev-model的資料雙向(重要)

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body&