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

資訊專(zhuān)欄INFORMATION COLUMN

用RxJS和react開(kāi)發(fā)mac地址輸入框

CastlePeaK / 2370人閱讀

摘要:項(xiàng)目簡(jiǎn)介本次使用了和開(kāi)發(fā)了一個(gè)地址輸入框,主要實(shí)現(xiàn)的功能有限制輸入符合條件的字符并每隔兩位可以自動(dòng)添加用于分割的冒號(hào)。項(xiàng)目屏蔽了的事件處理,同時(shí)使用來(lái)手動(dòng)控制光標(biāo)。繼承于和因此同時(shí)具有和兩者的方法。后面的和都是需要利用最新的來(lái)進(jìn)行判斷的。

項(xiàng)目簡(jiǎn)介

本次使用了RxJS和react開(kāi)發(fā)了一個(gè)mac地址輸入框,主要實(shí)現(xiàn)的功能有限制輸入符合條件的字符1-9,a-f,并每隔兩位可以自動(dòng)添加用于分割的冒號(hào)。項(xiàng)目屏蔽了react的事件處理,同時(shí)使用setSelectionRange來(lái)手動(dòng)控制光標(biāo)。可以查看項(xiàng)目的demo,項(xiàng)目地址

RxJS簡(jiǎn)介

RxJS 是 Reactive Extensions 在 JavaScript 上的實(shí)現(xiàn),具體來(lái)說(shuō)是一系列工具庫(kù),包括事件處理,函數(shù)節(jié)流,延時(shí)等函數(shù),RxJS應(yīng)用了’流‘的思想,同時(shí)具有事件和時(shí)間的概念。RxJS也可以用于處理異步流程,比起Promise具有可取消和可延遲,重試等優(yōu)點(diǎn)。Promise vs Observable
RxJS中有兩個(gè)比較重要的概念,分別是Observable和observer。Observable可以使用create,of,from,fromEvent等方法來(lái)產(chǎn)生流,而Observer可以對(duì)流進(jìn)行觀察。最后兩者通過(guò)subscribe來(lái)結(jié)合,例子如下:

var Observable = Rx.Observable.create(observer => {
    observer.next(2);
    observer.complete();
    return  () => console.log("disposed");
});

var Observer = Rx.Observer.create(
    x => console.log("Next:", x),
    err => console.log("Error:", err),
    () => console.log("Completed")
);

var subscription = Observable.subscribe(Observer);

來(lái)自構(gòu)建流式應(yīng)用—RxJS詳解

更多關(guān)于RxJS,可以閱讀Introduction | RxJS - Javascript library for functional reactive programming.

項(xiàng)目結(jié)構(gòu)
    // 監(jiān)聽(tīng)事件,發(fā)起流和處理流
    componentDidMount () {
    this.t = ReactDOM.findDOMNode(this.refs.t)
    let keydownValue = Rx.Observable.fromEvent(this.t,"keydown").map(e => e.key.toUpperCase())
    this.sa = keydownValue.filter(value => value.length === 1 && value.match(/[0-9A-F]/)).subscribe(value => {this.setColon("before");this.insertValue(value); this.setColon();this.setDomValue()})
    // 省略類(lèi)似的部分
    }
    // 取消訂閱
    componentWillUnmount() 
    this.sa.dispose()
    // 類(lèi)似的部分省略
    }
    
    // 一些用到的方法,這里省略
    
    
    // 取消原生的事件監(jiān)聽(tīng)
    render() {
      return (
        
e.preventDefault()} ref="t"/>
); }
項(xiàng)目詳解

首先使用Rx.Observable.fromEvent來(lái)監(jiān)聽(tīng)輸入框的按鍵事件,并獲取按鍵的key值,保存為keydownValue

 let keydownValue = Rx.Observable.fromEvent(this.t,"keydown")
 .map(e => e.key.toUpperCase())

接著首先考慮輸入字符的情況,在這里,顯示篩選出按鍵符合要求的情況,接著在subscribe中對(duì)數(shù)據(jù)進(jìn)行處理。在插入新的字符之前和之后,都需要判斷是否在前面加上冒號(hào),最后使用setDomValue來(lái)讓保存在state中的value顯示到輸入框上。

    this.sa = keydownValue
        .filter(value => value.length === 1 && value.match(/[0-9A-F]/))
        .subscribe(value => {
          this.setColon("before");
          this.insertValue(value); 
          this.setColon();
          this.setDomValue()
        })

判斷是否需要插入冒號(hào)的函數(shù)setColon,需要排除前面沒(méi)有字符和周?chē)呀?jīng)有冒號(hào)的情況。

  setColon = type => this.state.value.length && 
      (type !== "before" ? !this.isNearColon() : !this.isLastColon()) && 
      !(this.state.value.slice(0, this.state.pos).replace(/:/g, "").length%2) && 
      this.insertValue(":")

插入新字符的函數(shù)。在記錄的光標(biāo)位置pos值上插入新的字符,然后改變光標(biāo)位置。如果在字符末尾有未完成的字符對(duì)(即1f:的形式)又在中間插入新的字符串且字符對(duì)已經(jīng)到達(dá)六個(gè),則刪掉最后一個(gè)字符對(duì)。

  insertValue = value => {
    if (this.state.value.length !== 17) {
      this.setState({
      ...this.state,
      value: this.state.value.slice(0, this.state.pos) + 
        value + this.state.value.slice(this.state.pos, this.state.value.length)
      })
      this.setPos(this.state.pos + 1)
      if (this.state.value.split(":").length === 7) {
        this.setState({
        ...this.state, 
        value: this.state.value.slice(0, this.state.value.lastIndexOf(":"))
        })
      }
  }}

接著是講解關(guān)于刪除的流,篩選按鍵值為"BACKSPACE"的流,執(zhí)行deleteValue方法和setDomValue

    this.sb = keydownValue.filter(value => value === "BACKSPACE")
    .subscribe(() => {
      this.deleteValue()
      this.setDomValue()
    })

deleteValue,在value和位置都大于零時(shí)才執(zhí)行,如果刪除后字符后,新的最后一個(gè)字符是冒號(hào),則自動(dòng)刪掉該冒號(hào)。

  deleteValue = () => {
    if (this.state.value.length && this.state.pos) {
      this.setState({
      ...this.state, 
      value: this.state.value.slice(0, this.state.pos - 1) + 
      this.state.value.slice(this.state.pos, this.state.value.length)
      })
      this.setPos(this.state.pos - 1)
      if (this.isLastColon()) {
        this.deleteValue()
      }
    }
  }

接著是訂閱了左右方向鍵移動(dòng)的流,比較簡(jiǎn)單,就不詳細(xì)解釋了。

    this.sc = keydownValue
        .filter(value => value === "ARROWLEFT")
        .subscribe(() => this.moveLeft())
    this.sd = keydownValue
        .filter(value => value === "ARROWRIGHT")
        .subscribe(() => this.moveRight())
 
      moveLeft = () => this.state.pos > 0 && 
      this.setState({...this.state, pos: this.state.pos - 1})
      moveRight = () => this.state.pos !== this.state.value.length && 
      this.setState({...this.state, pos: this.state.pos + 1})

最后是讓光標(biāo)跳到pos的處理,setSelectionRange本用于文字的選擇,但如果前兩個(gè)參數(shù)為一樣的數(shù)值,可以達(dá)到讓光標(biāo)跳到指定位置的效果。

    this.se = keydownValue.subscribe(() => this.goPos())
    goPos = () => this.t.setSelectionRange(this.state.pos, this.state.pos)
170624更新

原本的模式跟react關(guān)系較少,因此修改調(diào)整了一下,主要的變化是啟用了Subject,setStateAsync,在這里先介紹一下。

Rx.Subject

Subject繼承于Obserable和Observer,因此同時(shí)具有Obserable和Observer兩者的方法。通過(guò)來(lái)自于Observable的multicast方法可以掛載subject,并得到擁有相同執(zhí)行環(huán)境的多路的新的Observable,關(guān)于他的訂閱實(shí)際上是掛載在subject上。最后需要手動(dòng)connect。 RxJS 核心概念之Subject,30 天精通 RxJS(24): Observable operators - multicast, refCount, publish, share

var source = Rx.Observable.from([1, 2, 3]);
var multicasted = source.multicast(new Rx.Subject())

// 通過(guò)`subject.subscribe({...})`訂閱Subject的Observer:
multicasted.subscribe({
  next: (v) => console.log("observerA: " + v)
});
multicasted.subscribe({
  next: (v) => console.log("observerB: " + v)
});

// 讓Subject從數(shù)據(jù)源訂閱開(kāi)始生效:
multicasted.connect();

其實(shí)可以用refCount來(lái)避免connect,用publish來(lái)代替 multicast(new Rx.Subject()),最后用share代替publish 和 refCount,因此代碼可以寫(xiě)成

var multicasted = source.share()
setStateAsync

組件改為受控組件之后,setState中的異步特性展示了出來(lái),setState后的下一步獲取setState并不是最新的state,影響了程序的正常使用。
例如之前的新增函數(shù)的訂閱。后面的inserValue和setColon都是需要利用最新的state來(lái)進(jìn)行判斷的。

    this.sa = keydownValue
      .filter(value => value.length === 1 && value.match(/[0-9A-F]/))
        .subscribe(value => {
          this.setColon("before");
          this.insertValue(value); 
          this.setColon();
          this.setDomValue()
        })

可以在setState的第二個(gè)參數(shù)中傳入回調(diào)函數(shù)來(lái)解決這個(gè)問(wèn)題,于是函數(shù)變成了這樣,一層又一層的回調(diào),十分不美觀

this.sa = keydownValue
  .filter(value => value.length === 1 && value.match(/[0-9A-F]/))
    .subscribe(value => {
      this.setColon("before", () => {
        this.insertValue(value, () => {
          this.setColon()
        })
      })
    })
    

接著在網(wǎng)上找到了setStateAsync的函數(shù),原理就是將setState轉(zhuǎn)換成promise的形式,接著就能愉快的使用async await的語(yǔ)法來(lái)修改state了。React中setState同步更新策略

  setStateAsync = state => new Promise(resolve => this.setState(state,resolve))
實(shí)際的調(diào)整

在componentDidMount中把keydownValue設(shè)置為同時(shí)具有Observable和Observe的方法的Subject,他一方面可以使用Observer的onNext方法來(lái)添加新的數(shù)據(jù),另一方面可以繼續(xù)使用Observable的操作符來(lái)對(duì)數(shù)據(jù)進(jìn)行處理。

this.keydownValue = new Rx.Subject()
let multicasted = this.keydownValue.map(e => e.key.toUpperCase()).share()
this.sa = multicasted
  .filter(value => value.length === 1 && value.match(/[0-9A-F]/))
    .subscribe(async value => {
    await this.setColon("before")
    await this.insertValue(value)
    await this.setColon()
    this.goPos()
  })
//下略    

組件的render函數(shù)修改為

  

handleE函數(shù)繼續(xù)禁止默認(rèn)事件,調(diào)用了新設(shè)置的Subject(keydownValue)的onNext方法,可以使得綁定在keydownValue上的訂閱獲得數(shù)據(jù)

  handleE = e => {e.preventDefault();this.keydownValue.onNext(e)}

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/94223.html

相關(guān)文章

  • Rxjs 響應(yīng)式編程-第六章 使Cycle.js的響應(yīng)式Web應(yīng)程序

    摘要:我們將使用,這是一個(gè)現(xiàn)代,簡(jiǎn)單,漂亮的框架,在內(nèi)部使用并將響應(yīng)式編程概念應(yīng)用于前端編程。驅(qū)動(dòng)程序采用從我們的應(yīng)用程序發(fā)出數(shù)據(jù)的,它們返回另一個(gè)導(dǎo)致副作用的。我們將使用來(lái)呈現(xiàn)我們的應(yīng)用程序。僅采用長(zhǎng)度超過(guò)兩個(gè)字符的文本。 Rxjs 響應(yīng)式編程-第一章:響應(yīng)式Rxjs 響應(yīng)式編程-第二章:序列的深入研究Rxjs 響應(yīng)式編程-第三章: 構(gòu)建并發(fā)程序Rxjs 響應(yīng)式編程-第四章 構(gòu)建完整的We...

    EastWoodYang 評(píng)論0 收藏0
  • 大廠前端面試考什么?

    摘要:面試流程如果你時(shí)間緊張或是在職,大部分大公司是支持第一輪電話面試的,而騰訊,阿里的面試基本前兩輪都是電話面。組員面總體來(lái)說(shuō)考察的東西較基礎(chǔ)。也有會(huì)問(wèn)你設(shè)計(jì)模式,各種繼承方法的對(duì)于大廠的面試來(lái)說(shuō),重要性可能比還要高。 背景 我最近一個(gè)月面試了20來(lái)個(gè)公司,其中有你們應(yīng)該都聽(tīng)過(guò)的bat,今日頭條,京東,網(wǎng)易,大疆,oppo,還有shopee,招商金科,有贊等比較不錯(cuò)的公司,收獲了六個(gè)off...

    jubincn 評(píng)論0 收藏0
  • 使 AVA 做自動(dòng)化測(cè)試

    摘要:?jiǎn)卧獪y(cè)試,測(cè)試一個(gè)簡(jiǎn)單的組件。接口測(cè)試,用戶(hù)信息接口測(cè)試。學(xué)習(xí)借鑒,一些使用做測(cè)試的開(kāi)源項(xiàng)目。這里使用到的內(nèi)置斷言斷言結(jié)果值等于我們想要的預(yù)期值,則測(cè)試通過(guò)。在里放入一個(gè)函數(shù),函數(shù)自動(dòng)執(zhí)行,里面執(zhí)行的結(jié)果必須拋出錯(cuò)誤,則測(cè)試通過(guò)。 目錄 1、為什么選擇 AVA ?2、API 概覽。3、準(zhǔn)備工作。4、單元測(cè)試,測(cè)試一個(gè)簡(jiǎn)單的工具函數(shù)。5、使用 Promise、Async/await、Ob...

    Cruise_Chan 評(píng)論0 收藏0
  • FCC 成都社區(qū)·前端周刊 第 11 期

    摘要:正式發(fā)布已正式發(fā)布,新版本重點(diǎn)關(guān)注工具鏈以及工具鏈在中的運(yùn)行速度問(wèn)題。文章內(nèi)容包括什么是內(nèi)存,內(nèi)存生命周期,中的內(nèi)存分配,內(nèi)存釋放,垃圾收集,種常見(jiàn)的內(nèi)存泄漏以及如何處理內(nèi)存泄漏的技巧。 1. Angular 6 正式發(fā)布 Angular 6.0.0 已正式發(fā)布,新版本重點(diǎn)關(guān)注工具鏈以及工具鏈在 Angular 中的運(yùn)行速度問(wèn)題。Angular v6 是統(tǒng)一整體框架、Material ...

    lentrue 評(píng)論0 收藏0
  • FCC 成都社區(qū)·前端周刊 第 11 期

    摘要:正式發(fā)布已正式發(fā)布,新版本重點(diǎn)關(guān)注工具鏈以及工具鏈在中的運(yùn)行速度問(wèn)題。文章內(nèi)容包括什么是內(nèi)存,內(nèi)存生命周期,中的內(nèi)存分配,內(nèi)存釋放,垃圾收集,種常見(jiàn)的內(nèi)存泄漏以及如何處理內(nèi)存泄漏的技巧。 1. Angular 6 正式發(fā)布 Angular 6.0.0 已正式發(fā)布,新版本重點(diǎn)關(guān)注工具鏈以及工具鏈在 Angular 中的運(yùn)行速度問(wèn)題。Angular v6 是統(tǒng)一整體框架、Material ...

    NusterCache 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<