前端mvvm框架底层学习(六、最初级的双向绑定)

前言

上一篇《前端mvvm框架学习(五、json对象+简单css及style处理)》介绍了我们如何实现一个简单的MVVM处理对象中函样式的处理属性的例子。真实项目中,我们要处理的内容其实不只是css及style样式处理,其他的属性值,如value等,在这一篇中我们来实现对一个input框进行最简单双向绑定,怎么简单怎么来吧,我们还是引用lodash库和还是用传统的方式拼接html字符串的方式来处理View层吧,还是使用模版函数来处理,直接用lodash的template函数,然后我们给input框绑定oninput的函数来进行反向绑定。

接着上一篇的代码,我们修改并增加一个input框,并与一个数值进行双向绑定


See the Pen MVVM two-way data binding by Nelson Kuang (@nelsonkuang) on CodePen
1

VIEW层代码:

<div id="input-area">
  <input type="text" class="form-control" data-hotkey="xxxhotkey" name="search" value="dfdf" placeholder="Search or jump to…" id="my-input" />
  <span>The value of the input is <b id="my-input__val">dfdf</b></span> 
</div>

MODEL层代码 :

var newPerson = {
  myInput: 'dfdf'
}

VIEWMODEL层代码:

function bindInputModel() {
  var inputEl = document.querySelector('#my-input')
  if(inputEl && inputEl.value !== undefined) {
    inputEl.oninput = function (e) {
      console.log(newPerson.myInput)
      if(e.target.value !== newPerson.myInput) {
        newPerson.myInput = e.target.value
      }
    }
  }
}
function updateInputArea(newVal, oldVal) {
  var el = document.querySelector("#input-area")
  // 传统的拼接html字符串的方式实现更新视图View
  var compiled = _.template(
    '<input type="text" class="form-control" data-hotkey="xxxhotkey" name="search" value="${ myInput }" placeholder="Search or jump to…" id="my-input" /><span>The value of the input is <b id="my-input__val">${ myInput }</b></span>'
  )
      el.innerHTML = compiled({myInput: newVal})
    bindInputModel()
}
Object.defineProperty(newPerson, "myInput", {
  set: function(x) {
    if (x !== this.oldPropValue) {
      updateInputArea(x, this.oldPropValue)
      this.oldPropValue = x
    } else {
      console.log("myInput的值没变")
    }
  },
  get: function() {
    console.log("in property get accessor")
    return this.oldPropValue
  },
  enumerable: true,
  configurable: true
})
bindInputModel() // 预绑定

现在尝试更新MODEL层数据,VIEW层应该就可以自动更新了。

newPerson.myInput = '新的值'

或者直接修改input输入框的值,紧跟着的文字应该会跟着变,但现在出现了一个新的问题,就是input框每次编辑都会出失去了焦点,这是一个问题。

结束语

通过上面的demo我们可以知道,要实现双向绑定是需要给input框绑上oninput的方法,然后把变化的值传回给model数据,这种做法是比较正路的方法,但却带出了一个新的问题,就是每次编辑都会失去了焦点,这当然是不能接受的,要解决这个,痛点,其实就是解决局部更新的问题,下一篇我们继续来优化上面的Demo,看看可以玩出什么花样。

作者: 博主

Talk is cheap, show me the code!

发表评论

电子邮件地址不会被公开。

Captcha Code