微信 小程序(三):选座系统2(主要内容:数组的动态更改)

人生无趣且不易,一起找点乐子吧。欢迎评论,和文章无关也没问题。

 

 

 

上篇文章我们主要说到了列表的渲染,给定个数组,循环遍历“画”在界面上,最后我们也提到,如果想要改变界面,只要相应的改变对应数组的内容就可以了。

This time我们来谈下怎样从界面获得点击位置,然后在脚本里处理,并修改数组的相应位置的内容,也就是实现选座,离座的功能。

首先我们先来捋清一下思路,我们的选座需要什么功能,页面上许多的icon,当我们选中后点击,要触发选座事件,将我们点击的相应的icon所对应的数组元素改变。我们最初设想,有人选了的座位就显示成红色,没人选的就成绿色,表示可选,那我们就拿蓝色当做我们当前选择的位置好了。那这个功能的主要核心点就是,我从页面获得什么数据(被点击座位映射到数组中的位置),脚本里面怎样准确的处理到我们点击icon的对应数组信息?

思维敏捷的同学可能已经想到了,既然要改变所点击的icon对应的数组的信息,那只要获得那个icon所处数组的位置就可以了(也就是下标)。没错,我们只要从页面获取到点击icon的下标,相应的去改变数组的值就好。

那么问题来了,怎样得到icon的下标?这里呢,其实icon标签可以有个id属性(自定义属性),我们可以来设置,分别为icon赋予不同的id,在绑定的函数里,我们就来获取id当做下标来用。那么第一个icon的id就让他等于零,第二个等于1,依次下推。至于怎么实现,当然不用我们一个个手动输进去啦。我上次不是说的吗,那样手疼(即使是有文化的莽夫),但别忘了,我们的界面是通过循环画出来的,循环的时候靠的数组的item,因为我们只用到了他的内容,这次我们需要他的下标,它还有个默认的index属性啊,好好利用。

这次我们这样写:

<view wx:for="{{color}}" wx:for-index='x' wx:for-item="r">
    <icon wx:for="{{r}}" wx:for-index='y' wx:for-item="c" type='success' bindtap='click' id='{{x*clo+y}}' color='{{c}}'></icon>
    </view>

外层view循环有多少行,即二维数组里有多少一维数组,内部的icon再画出每一行的内容。这里没什么新内容,只是理解上上了层高度,我也一起帮大家捋下思路,我们都来给数组的index和item起了个别名,index理解为下标就可以,希望你的第一门编程语言是c或者java,如果是python可能会稍稍蒙一下(python的循环很少用下标引用,一般从迭代器中取)。我直接起别名是x,y了,这样恰好也是我们引用二维数组的习惯。item分别对应了r和c,没什么特别的深意,就是row和column,很好理解吧。其实核心在id怎样去写,多了个绑定事件click,我们等下讲,这里的处理,我认为是比较冗余了,但是我没找到更好的解决办法,也拿出来跟大家交流下吧。我这里返回的id其实是数组的第几个元素,也就是把二维数组换成一位数组后的下标,好像越解释越迷糊了。举个例子吧,比如三行三列的数组,第一行的最后一个元素下标是2,第二行第一个是3,就是这个意思。这里谈到下,其实id的内容不是限制的,可以是字符类型(也就是上面提到的自定义属性,属性是自己设置的),也就是说完全可以赋值“3  5 ”,当成3行5列来处理,但这时函数里面获得的也是char或者str类型,在后面的setdata步骤的时候会引起不必要的麻烦,往后看,后面详谈。大家可以去尝试,如果成功了,可能会比我这里少写几步吧。id属性里面的clo是js里面的数值(从后台获取的信息,理解成一行有多少个座位就好了),其实是自己定义的二维数组的列数,这样大家就明白了吧。(例如你在js里面定义了3x2的数组,记得定义clo变量为2,不用担心我们不能动态变化它,后面会谈。)

这里我们来分析下click函数的写法。首先我先讲下在函数里面变量的获取吧。

click: function (e) {
    var th = this;
    var id = e.target.id;
    var y = (id)%this.data.clo;
    var x = (id-y)/this.data.clo;
    var col = 'color[' + x + '][' +y+ ']';
    var color = th.data.color[x][y]
}

(this.data.clo和我们上面说的那个id属性里的clo是一个东西)

我们一个个来说,首先第一个th,没啥就是让他当this用,为什么要特意声明一次,这里要说一下,当你在一个函数中直接用this的时候不会出错,但是如果这个函数里面还有函数,在里面的函数里使用我们的this时,就会not define,在控制台就会出错。这时作用域的问题我没太去深入的理解,大家感兴趣去查查吧。第二个(this.data.clo 我们刚刚说了,他就是定义的二维数组列数,自己去定义它),id就是获取页面我们设置的那个id(也就是icon中自定义的那个id),通过函数的默认参数,我这里设成了e,通过e的target方法就可以去获的绑定标签的属性。后面的x,y当然就是我们要得到对应的二维下标了。但还是不明白,还是那个问题,为什么,不把页面的id设成id=“{{x   y}}”,然后js得到后用splite去分割下分别给x,y。就不用像这样还要对id取余啊,做除法啊什么的。其实这里有原因。我们先跨过几步,先来说下setdate怎么实现。

this.setData({
                color[x][y]: 'blue',
              })

假设我们已经得到了x,y。但是我们可以通过上面的方法给color赋值吗?这里很可恶,会出错,他会说不认识color[x][y]。接下来是我的理解,在setData中,你的变量必须是“”不变的“,(很二的问题,不变还叫变量)比如你换成color【0】【1】就没问题,因为变量未定义,所以我们怎么处理这里呢。很简单,其实就是在setData外先把color【x】【x】(也就是先固定,再引用)对应的形式写好当成个字符串,然后用字符串替换图中的color【x】【y】。这就是为什么在上上张图中有

click: function (e) {
    var th = this;
    var id = e.target.id;
    var y = (id)%this.data.clo;
    var x = (id-y)/this.data.clo;
    var col = 'color[' + x + '][' +y+ ']';
    var color = th.data.color[x][y]
}

var col = 'color[' + x + '][' +y+ ']',这里赋值的内容就很好看懂了吧。回到最初的问题,页面为何不是id=‘{{x   y}}’。我们来看col,这时的x和y是数值型,这样拼接完后col就是“color[0][1]”这种形式。如果按我们说的那种写col就是这种类型了“color[“0”][“1”]”,显然这种引用是错的,因为下标不能字符类型。那在得到x,y后强制转换不行吗?理论上是没问题的,但是强制转换那里还有坑,我用过几次网上查到的方法,皆以失败告终,转换挺麻烦的,我不知道现在的bug有没有修复,如果可以,其实大家完全可以采用上面说的那种方法。

最后一个变量color其实就是得到当前点击的那个位置,是什么颜色啦。然后我们根据他去处理。(看color数组对应位置的颜色)

这里我们分析一下,我们设置的是已选座位是红色,未选为绿,当前选择是蓝。

那么我们的函数就应该是

if(color=='red'){
    提示此位置已被选
}else if(color == 'green'){
    这里还要进行两次判断,是否已经选了座
    if(已选)
        提示 你已经选择了 不能重复选择
    else
        设置选择位置的color为blue
}else{
    pass(先过吧,这里只剩蓝色没处理,我们后面处理)
}

 

怎样判断是否已经选座呢,这里其实和简单,我们定义一个变量,随意的定初始值为0吧,当我们成功选座后,就把他改为1,离座后再改为零,来当做我们是否选座的判定。(就是自定义一个开关,表示是否选座的状态,立一个flag)

红色的判定,内容大家可以随意写啦。无所谓啦(我这里提个警告,告诉用户已选)

if(color == 'red'){
      wx.showModal({
        title: 'Warning',
        content: 'The seat have been choiced.',
        success: function (res) {
          console.log('用户点击确定')
        }
      })
      }

我们来看下面的:(seatnow就是上面说的开关,看看你是否当前选了座)

else{
      if (th.data.seatnow == 0) {//是否选择了座位 未选
            this.setData({
              id: id,//
              x: x,//这里的东西我们要用来写离座的函数,直接留下,不用再进行获取了(对此函数无意,先记着我们把选择的座位id,x,y存下了,后面讲为什么)
              y: y,//
            })
        wx.showModal({
          title: 'Confirm',
          content: 'Make sure you chose this seat  ' + id + '(+1)',
          success: function (res) {
            if (res.confirm) {
              th.setData({
                [col]: 'blue',//选座成功,选择的位置编程蓝色,选座状态变为1
                seatnow: 1
              })
              console.log('用户点击确定')
            } else if (res.cancel) {
              console.log('用户点击取消')
            }
          }
        })
      } else if (color == 'green') {//已选
        wx.showModal({
          title: 'Warning',
          content: 'You have choiced a seat.',
          success: function (res) {
            console.log('用户点击确定')
          }
        })
      } else {//已选 且为蓝色
        wx.showModal({
          title: 'UserInfo',
          content: 'Username is  ' + 'john',
          success: function (res) {
            if (res.confirm) {
              console.log('用户点击确定')
            } else if (res.cancel) {
              console.log('用户点击取消')
            }
          }
        })
      }
    }

 

这样我们整个的逻辑处理就算完成了。这里要说明,这个if其实已经是click函数里面的函数了,这里再用this就要出错了(回到了为什么有th = this的那条代码)。

还有个离座的处理。在页面写一个按钮,绑定事件leave,处理很好写,和上面没什么不同,就是把颜色换成green,而不是blue了。

leave:function(e){
    var th = this;
    var x = this.data.x;//
    var y = this.data.y;//这里我们不再获取,click函数里面我们已经存了起来,直接拿来用(这里就用到了我们上面保存的座位信息,知道为什么了吧。我们需要下标在离座的时候把颜色变回来)
    var id = this.data.id;//
    var col = 'color[' + x + '][' + y + ']';
    wx.showModal({
      title: 'Confirm',
      content: 'Are you want to leave this seat?',
      success: function (res) {
        if (res.confirm) {
          th.setData({
            [col]: 'green',
            seatnow: 0
          })
          console.log('离开成功')
        } else if (res.cancel) {
          console.log('用户点击取消')
        }
      }
    })
  }

完成了,我给大家看下效果吧:

界面的设计大家自己去搞哈,我们就以第二行,第四个来做实验吧。点击:

确认:

这时候我们再点击其他绿色按钮:

点击红色的:

提示被选。我们离开座位试试:

点击离开:

确认:

ok,这次的文章就先到这里吧。希望对您有帮助,下次我们来谈谈怎样动态的生成数组,我们已经可以画出座位,还可以点击选座改变数组,从而改变座位布局。但是,最后一点,使用时,会有很多种班级的布局,不同的行列组合,每个教室都是一张图,我们当然还可以拿出莽夫的劲头,有多少个教室,我就画多少个界面。

如果不呢?这就是我们下次谈的内容。

当后台给我一个座位的字符串:"John None None Rose None",我就知道1号和4号座位上坐着人,别的地方都是空的。问题在于怎样根据这串字符去动态的生成color数组呢(生成了color数组,前面的绘制以及事件就都相应的完善了)。其实就是界面的初始化显示怎么去实现。(换种说法,我从数据库得到了个 六行八列 的消息,我怎样通过这个‘6 8’,生成那个color数组,从而动态改变了界面,真正使界面活起来。)

 

 

 

后记:

再次审看,啰里啰嗦,还是没讲太清楚,尤其是二维数组那块。其实很简单,for循环,有两个参数,item表示元素,index表示元素下标。再有就是取别名,无非就是为了在处理外层和内层循环时好理解罢了。

重点在于理解起的那几个别名分别代表什么。Fighting!

  • 4
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 20
    评论
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值