Baiduフロントエンド学院学習:動的データバインディング(二)

2090 ワード

タイトルの住所とソースコードの住所
深さオブジェクトを処理
一つの要求があります.もし入ってきた相手がもっと深い対象であるならば、つまりvalueは別の新しい対象でもいいです.その対象の属性にgetterとsetterを加えるべきです.私のやり方は各値が対象かどうかを判断して、それを返送して処理することです.
each(obj) {
  Object.keys(obj).forEach(key => {
    //           
    if (Object.prototype.toString.call(obj[key]) === '[object Object]') {
      //     
      this.each(obj[key])
    } else {
      this.convert(key, obj[key])
    }
  })
}
ここではObject.prototype.toString.call()を使って値がどのタイプかを判断します.typeofを使うと、object、array、nullはいずれもobjectに戻ります.
ウォッチを実現
タイトルにはもう一つの要求があります.$watchの機能を実現するために、Vueを使ったことがある学生は皆知っています.私たちはこの関数で値の変化を監視し、また一つのコールバック関数に伝えます.もし値が変わったら、コールバック関数を実行します.constructorには、コールバック関数を格納するための変数が追加されます.
...
this.watchProperties = {}
...
$watchおよびemitの関数を実装する.
ウオッチを格納するコールバック関数の作り方は一つの対象で処理します.keyは属性名で、valueはコールバック関数です.
$watch(name, fn) {
  this.watchProperties[name] = fn
}

emit(name, val) {
  if (this.watchProperties[name] && typeof this.watchProperties[name] === 'function') {
    this.watchProperties[name](val)
  }
}
convertに追加する:
convert(key, value) {
    ...
    Object.defineProperty(this.setData || this.data, key, {
      ...
      set: function (newValue) {
        ...
        //    emit    watchProperties       
        // key     
        // newValue       
        that.emit(key, newValue)
        ...
      }
    })
  }
最後のステップ、露出$watch方法:
constructor(json) {
    ...
    return {
      ...
      //      ,          
      $watch: this.$watch.bind(this)
    }
  }
ここでは、bindを使用して実行時の上下の環境を修正する必要があり、そうでなければwatchPropertiesにアクセスできない.
まだ完成していない機能
  • $watch関数は、比較的深いオブジェクトの属性を傍受することができません.
  • 新規に一例を作成すると、深いオブジェクトが入ってきたら、フラットになります.
    let app = new Observer({
      name: {
        a: 1,
        b: 2
      }
    })
    
    console.log(app.data)
    //    
    /*
      [object Object] {
        a: 1,
        b: 2
      }
    */