前言
上一篇《前端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,看看可以玩出什么花样。