赞
踩
在做项目的过程中,出现了和对象数组进行双向绑定的需求,如果是使用vue的话,只需要一个v-model就解决了,但是原生小程序就不行啦,但是这都是无法难住大佬们的,这次找到了一个大佬的解决方式,趁机学习学习。
官方文档地址:简易双向绑定 | 微信开放文档 (qq.com)
使用的方式非常简单,在value的前面加上model:就可以啦
<input model:value="{{value}}" />
(1)现在你有一个组件了,这是一个输入框,使用双向绑定
<input model:value="{{myValue}}" />
- // custom-component.js
- Component({
- properties: {
- myValue: String
- }
- })
<custom-component model:my-value="{{pageValue}}" />
(3)如果你使用了setData
setData会改变data中的数据,对应的,输入框中的数据也将会发生改变
来自Michaelfu的实现(双层对象):微信小程序实现双向绑定 - 掘)
通过输入框的输入事件,获取输入框的值,然后将这个值使用setData来进行更新。但是一个个获取值,然后使用setData更新太麻烦啦,所以将这个方法进行封装
- module.exports = {
- inputgetName(e) {
- // 从事件对象 e 中获取输入框的 data-name 属性值
- let name = e.currentTarget.dataset.name;
- // 用于存储更新后的数据对象
- let nameMap = {};
-
- // 通过判断 name 是否包含点符号 . 来确定是否存在多层级的数据绑定关系
- if (name.indexOf('.') !== -1) {
- let nameList = name.split('.');
- // 判断多层级的第一个属性是否存在于 this.data 中,
- 如果存在,将其保存到 nameMap 中,
- 否则创建一个空对象并保存到 nameMap
- if (this.data[nameList[0]]) {
- nameMap[nameList[0]] = this.data[nameList[0]];
- } else {
- nameMap[nameList[0]] = {};
- }
- // 将输入框的值 e.detail.value 更新到 nameMap 中
- nameMap[nameList[0]][nameList[1]] = e.detail.value;
- } else {
- // 单层的数据直接更改
- nameMap[name] = e.detail.value;
- }
- this.setData(nameMap);
- }
- };
2、使用方法
(1)为你的js找一个home,例如:我是放在了utils中,文件命名为binds.js
(2)将刚刚js代码复制进去(就是下面这个啦)
- module.exports = {
- inputgetName(e) {
- // 从事件对象 e 中获取输入框的 data-name 属性值
- let name = e.currentTarget.dataset.name;
- // 用于存储更新后的数据对象
- let nameMap = {};
-
- // 通过判断 name 是否包含点符号 . 来确定是否存在多层级的数据绑定关系
- if (name.indexOf('.') !== -1) {
- let nameList = name.split('.');
- // 判断多层级的第一个属性是否存在于 this.data 中,
- 如果存在,将其保存到 nameMap 中,
- 否则创建一个空对象并保存到 nameMap
- if (this.data[nameList[0]]) {
- nameMap[nameList[0]] = this.data[nameList[0]];
- } else {
- nameMap[nameList[0]] = {};
- }
- // 将输入框的值 e.detail.value 更新到 nameMap 中
- nameMap[nameList[0]][nameList[1]] = e.detail.value;
- } else {
- // 单层的数据直接更改
- nameMap[name] = e.detail.value;
- }
- this.setData(nameMap);
- }
- };
(3)在需要用到双向绑定的页面中引用
js文件:
- // 引用公共app.js公共内容
- var app = getApp();
- // 引入双向绑定js
- var binds = require('../../../utils/binds')
-
xml文件:
注意:控件需要bindinput
绑定inputgetName方法,data-name
属性也要与需要操作的变量匹配,否则会失效,这样就完成了。
上面的方式几乎可以满足大多数的场景啦,如果是多层嵌套的情况,可以将js文件的代码替换为下面的:(注明:由于时间原因还没来得及测试这段代码,谨慎使用嗷)
- module.exports = {
- inputgetName(e) {
- // 从事件对象 e 中获取输入框的 data-name 属性值
- let name = e.currentTarget.dataset.name;
- // 用于存储更新后的数据对象
- let nameMap = {};
-
- // 通过判断 name 是否包含点符号 . 来确定是否存在多层级的数据绑定关系
- if (name.indexOf('.') !== -1) {
- let nameList = name.split('.');
- // 判断多层级的第一个属性是否存在于 this.data 中,如果存在,将其保存到 nameMap 中,否则创建一个空对象并保存到 nameMap
- if (this.data[nameList[0]]) {
- nameMap[nameList[0]] = this.data[nameList[0]];
- } else {
- nameMap[nameList[0]] = {};
- }
- // 将输入框的值 e.detail.value 更新到 nameMap 中
- nameMap[nameList[0]][nameList[1]] = e.detail.value;
- } else {
- // 单层的数据直接更改
- nameMap[name] = e.detail.value;
- }
- this.setData(nameMap);
- }
- };
以上是我的个人浅薄的见解,如果有问题请您指出~ 如果您读完本文有未解决的疑惑,可以在下方评论,我们一起解决。如果这篇文章对您有帮助,请点个赞给博主一点鼓励。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。