跳转至

脚本及事件、数据绑定

事件绑定

在上一篇教程中,我们介绍了可以用于界面设计的设计器:设计器可以拖动一些常见控件到页面中,并在页面上进行摆放或者调整大小,属性等。对于一个按钮,例如点击它,对应的事件动作处理,却是设计器所不能处理的。

例如,上篇文章给出的界面设计稿是label显示了一个"Hello World",我们通过点击下面的 OK 按钮,让它更改文本为"Hello RT-Thread"。

在设计器中,我们先选中这个button1对象,在设计器的属性栏中,把调用属性的bindtap栏内容填上onButton;

bindtap of button

然后打开这个页面的脚本文件page1.js。这个脚本文件是一个JavaScript文件,以完整的ES5语法形式使用。这里可以在page对象中添加对应的onButton方法,我们先简单的在其中输出"clicked"的日志信息:

var page = {
    onButton: function(e)
    {
        console.log("clicked");
    }
};

Page(page);

然后我们可以按工具栏的运行按钮进行仿真。

run

它会直接在PC上以模拟执行方式运行,这样开发工程师就可以直接查看效果,而不需要一定更新到开发板上才能看到效果。在PC上执行和在板子上执行,基本上是没太多差别的(只有后续涉及到动画时,会有速度上的差异)。

仿真效果如下:

simulator bindtap

我们可以看到,当点击 OK 按钮时,后面的命令行会输出"clicked"的日志信息。

数据设定

基于上一节,我们再介绍如何去更改label的显示文本。在一个page对象上,都会存在setData方法,可以通过这样的方式来设置这个page对象内控件的属性,例如这里添加的label1对象的文本信息:

var page = {
    onButton: function(e)
    {
        console.log("clicked");

        this.setData({label1: { value : "Hello RT-Thread", refresh : true}});
    }
};

Page(page);

在这个脚本中,我们会调用this.setData方法,并传递了一个对象进去:

{label1: { value : "Hello RT-Thread", refresh : true}}

这个参数对象的意思就是告诉page,我需要把名字是"label1"的对象的值设置成"Hello RT-Thread",同时刷新这个对象(refresh : true)。

关于不同针对不同对象的setData,可以查看我们的API手册获得更多的信息。

页面切换

以上是一个页面的情况,我们可以多创建一些页面,选中工程文件树区域的UI文件,在上面点击鼠标右键,选择新建,直接点击确定,然后会创建出page2,在page2上我们只添加一个按钮,同时调整它的文本内容为"Back",以及同样的,先设置它的bindtap属性为onButton

页面2

回过头来看page1,因为它是首先要显示的页面,我们对button1的bindtap函数做一定的改动,能够点击它后,跳转到page2:

var page = {
    onButton: function(e)
    {
        console.log("clicked");

        // this.setData({label1: { value : "Hello RT-Thread", refresh : true}});

        pm.navigateTo({url: "page2/page2"});
    }
};

Page(page);

(对于原来的 this.setData 我们先注释掉)

在这里,当点击事件发生时,将执行pm.navigateTo({url : "page2/page2"}),即让UI导航切换到page2/page2的URL。相当于切换到page2。同样的,当切换到page2以后,对于唯一的Back按钮,我们可以点击它,需要它回到page1,那我们就需要在page2的JS脚本代码中这样些:

var page = {
    onButton : function(e)
    {
        pm.navigateBack();
    }
};

Page(page);

即当page2的button按下时,会调用pm.navigateBack(),切换回page1。

另外,函数redirectTo也可供用于切换page。与navigateTo不同的是,redirectTo会先关闭当前page再跳转到目标page。 如果在上述Sample的page1中执行pm.redirectTo({url : "page2/page2"})后,再执行page2中pm.navigateBack(),界面不会切换到page1,因为page1已经关闭,此时界面回切换到一个空page。因此在此仅做说明,不推荐使用。

  • 实际效果

实际效果demo1

Sample-计算器

上一小节中,我们了解到了事件,以及setData绑定数据的情况。作为小结,我们这个章节以实现一个计算器来结束。首先是计算器界面本身的UI设计。

首先咱们给page控件设置一个带有计算器图片的背景图

设置背景

然后拖动一个Button控件到设计器,将透明度属性设置为0,设置控件名称值为:num1bindTap属性绑定onButton事件,给正常图片选择一张半透明图片,删除默认点击图片的信息,根据需求设置控件大小,并删除对应文本信息。

拖动控件

重复以上方法尽数添加计算器所使用到的功能按钮。

然后是对应的JavaScript脚本。

var page = {
  data: {
    result: ''
  },
  op: 'null',
  left: 0,

  onButton: function(e) {
    var result = this.data.result;
    console.dir(e);

    switch (e.target.id) {
      //根据控件ID设置result控件显示
    case "num0":
    case "num1":
    case "num2":
    case "num3":
    case "num4":
    case "num5":
    case "num6":
    case "num7":
    case "num8":
    case "num9":
      //获取到被点击控件对应数值
      var num = e.target.id.substring(3, 4);
      console.log(num);

      if (result != '0') result += num;
      else result = num;

      break;
    case "numdot":
      if (result.indexOf(".") > 0) break;
      else if (result.length == 0) result = "0.";
      else result += ".";
      break;
    case "btnback":
      //退格
      if (result.length == 1) result = '';
      else result = result.substring(0, result.length - 1);
      break;

    case "btnDiv":
      //除
      if (result != '') {
        this.op = "div";
        this.left = Number(result);
        result = '';
      }
      break;
    case "btnMul":
      //乘
      if (result != '') {
        this.op = "mul";
        this.left = Number(result);
        result = '';
      }
      break;

    case "btnSub":
      //减
      if (result != '') {
        this.op = "minus";
        this.left = Number(result);
        result = '';
      }
      break;
    case "btnAdd":
      //加
      if (result != '') {
        this.op = "plus";
        this.left = Number(result);
        result = '';
      }
      break;

    case "btnClear":
      //清除
      result = '';
      break;

    case "btnEqu":
      //等于
      if (this.op == 'null') break;

      //结果计算
      switch (this.op) {
      case 'div':
        //除
        var num = Number(result);

        if (num == 0) result = 0;
        else result = this.left / num;
        break;
      case 'mul':
        //乘
        result = this.left * Number(result);
        break;
      case 'minus':
        //减
        result = this.left - Number(result);
        break;
      case 'plus':
        //加
        result = this.left + Number(result);
        break;
      }

      this.left = 0;
      result = String(result);
      this.op = 'null';
      break;
    }

    if (this.data.result != result) {
      this.data.result = result;
      //设值并刷新控件
      this.setData({
        result: {
          value: this.data.result,
          refresh: true
        }
      });
    }
  },
};

Page(page);
  • 仿真效果:

效果展示

  • 实际效果

实际效果demo2

评论