黑马程序员技术交流社区

标题: 【上海校区】通过Observable解决搜索框问题 [打印本页]

作者: 不二晨    时间: 2018-10-23 09:38
标题: 【上海校区】通过Observable解决搜索框问题
观察者模式观察者模式也叫发布订阅模式. 最经典的用法就是在事件监听里面.
    <button onClick = "handle()">确认</button>    handle方法订阅了onClick事件,当用户点击(发布)onClick, handle方法触发复制代码大致提一下,网上对观察者模式的解释有很多. Observable就是基于观察者模式实现的
Observable方法的定义基本特征:
let ob = new Observable(obser => {    // 这个函数是“发布”    obser.next()})// 订阅了console.log(12)动作ob.subscribe({    next(){console.log(12)}})注:只有subscribe方法执行了才会执行"发布"函数复制代码在core-js中已对observable做了扩展,通过import "core-js/es7/observable"可以使用Observable
实现Observable方法便于理解,还是简单的实现一个Observable吧,代码如下
class SubscriptionObserver {    constructor(ob, debounceTime){        this.ob = ob || {};        this.debounceTime = debounceTime;        this.unSub = false;        this.timeout = null;    }    next(value){        if (!this.unSub && this.ob.next){            clearTimeout(this.timeout)            this.timeout = setTimeout(() => {                !this.unSub  &&this.ob.next(value);                this.timeout = null;            }, this.debounceTime)        } else {            this.ob.next(value);        }    }    error(){        if (!this.unSub && this.ob.error){            this.ob.error();        }    }    complete(){        if (!this.unSub && this.complete){            this.ob.complete();        }    }    unsubcribe(){        this.unSub = true;    }}class Observable {    constructor(SubscriptionOb) {        this.SubscriptionOb = SubscriptionOb;    }    subscribe(ob){        this.subOb = new SubscriptionObserver(ob, this.timeout);        return this.SubscriptionOb(this.subOb);    }    unsubcribe(){        this.subOb.unsubcribe()        return this;    }    debounceTime(timeout){        this.timeout = timeout;        return this;    }}复制代码
主要增加了debounceTime功能, 在debounceTime在lazy时间内只会执行最后一次next方法
搜索框的应用搜索框的搜索主要是要解决2个问题
代码如下
export default class Tudos extends React.Component {    state = {        text:""    }    // 搜索关键字接口    searchKeyWords(text){        return new Promise((resolve) => {            setTimeout(() => {                let list = [{...}...]                resolve(list)            }, 2000)        })    }    handleInput(dom) {        let oba = new Observable(ob => {            dom.oninput = e => {                ob.next(e.target.value)            }        }).debounceTime(500).subscribe({            next(value){getList(value)}        })    }    render() {        return (<div>            <input ref = {dom => dom && this.handleInput(dom)}/>        </div>)    }}复制代码总会在用户输入完500毫秒后执行next函数。这个上述代码已实现. 第二个问题还未解决!
引入RxJS安装
npm i @reactivex/rxjs --save;复制代码引入
import * as Rx from "@reactivex/rxjs";复制代码RxJS 当做是用来处理事件的Lodash .像这种复杂的事件处理第一个就是想到使用RxJS
具体的使用可以参考以下官方文档
代码如下
export default class SimpleSortableList extends Component {    componentDidMount() {            }    // 搜索关键字接口    searchKeyWords(text){        return new Promise((resolve) => {            setTimeout(() => {                let list = [{...}...]                resolve(list)            }, 2000)        })    }    handleInput(button){        Rx.Observable.fromEvent(button, 'input')        .debounceTime(500)        .switchMap(e => {            return Rx.Observable.create(ob => {                this.searchKeyWords(e.target.value).then(res => {                    ob.next(list)                })            });        })        .subscribe(text => console.log(text))    }    render() {        return (            <div className={prefix}>                <input ref = { dom => dom && this.handleInput(dom)} />            </div>        );    }}复制代码

【转载】
作者:fiveoneLei
链接:https://juejin.im/post/5bc84b375188255c554728f1




作者: 小影姐姐    时间: 2018-10-25 09:46

作者: 不二晨    时间: 2018-10-25 10:48

作者: 魔都黑马少年梦    时间: 2018-11-1 16:57





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2