日常工作总结-2016-02-19

最近几天,在做一个类似列表的一个界面,在做的时候碰到了很多问题和总结了一些经验,在这里有必要记录一下。设计图如下:


遇到的问题

页面看起来并不复杂,可以后台返回的数据并不是很完整,所以遇到了一些问题,有的问题在我看来不是很难我这里就不再描述了(以我的水平如果觉得不难那一定是非常简单了。。。 - -),具体有以下四个问题:

  1. 后台返回的交易类型有三种,根据每种交易类型展示不同的图片,可以参考上面到账详情那张图片。
  2. 请看最近到账那张图片,列表的到账状态有四种,根据不同的状态展示的文字颜色需要不一样。
  3. 后台返回的金额都是以分为单位的,而页面上展示的是以元为单位的。
  4. 详情页面的有些信息后台并没有返回给你,必须从列表页面来获取这些信息运用到这个界面上。

这就是遇到的几个比较让我头疼的问题,下面我来简单说一下每个问题的解决办法。


1. 问题一和问题二

问题一和二,其实就是模板语言上面的问题,现在加载页面有一些页面上要展示出来的数据其实是后台返回给你的。所以你要预先读取这些数据并通过浏览器渲染到你的页面上。基本做前端的同学应该都会用到模板语言,而我用的是handlebars这个模板语言(其实解决这个问题的办法是换一个模板语言,最后我会简单的说一下),我主要是描述一下用handlebars这个模板语言是怎么解决的。

handlebars当中的#if只能来做这个变量存不存在的简单判断,而不能在if当中加一些参数的判断,所以这里我们需要引用handlebars helper,在我理解这个其实就是用来补充handlebars中的不足的,在handlebars helper中可以进行一些复杂的判断,以我用的这个helper为例来分析一下,我这个helper的功能是这样的,他可以判断后台返回的一个字段的类型,如果类型是微信支付就显示微信支付的图标,如果是支付宝就显示支付宝的图标。

1
2
3
4
5
6
7
8
9
10
11

//这里是注册了一个新的helper,名字叫做compare,而这个helper接受了三个参数,第一个和第二个参数是必填的,第三个参数是选填的
Handlebars.registerHelper("compare",function(v1,v2,options){
//比较参数 满足条件添加继续执行
if(v1 == v2){
return options.fn(this);
}else{
//不满足条件执行{else}部分
return options.inverse(this);
}
});

如上代码,注释写在了里面,我只想说一下options.fn(this),其实这个意思就是执行下面的部分,这个部分其实不是在我们的js函数中,而是在我们引用这个helper的那个html页面中出现# compare的这个地方。看如下代码:

1
2
3
4
5
6
7

//比较type是不是card
{#compare type 'card'}
<img src="img/ic_card.svg" alt="">
{else}
<img src="img/ic_weixin.svg" alt="">
{/compare}

如上,这个就是我在html页面的部分代码,options.fn(this)的功能就是执行# compareelse之间的代码。(以我浅显的理解,通俗的解释。。。。。)。

PS:少写了一个花括号是因为双花括号在markdown语法中不能正常显示出来。。。。

说完handlebars模板语言之后,我们来说另一种模板语言,template.js这个模板语法相比handlebars很轻量级,所以很适合移动端使用。他的语法和handlebars类似,而且他可以做一些比较复杂的逻辑判断,比如if判断来说他可以支持if a > b || ( a < c && a == d )这样的复杂判断。使用这样的模板语言,能够基本完成渲染时碰到的一些常用需求。


2. 问题三

后台返给我的数据是以为单位的,而我要显示为以为单位的并且保留两位小数,怎么办?其实这个函数是我网上搜索来的,因为我当时只是单纯的把返回的数据除以了100,这样是变成以为单位了,但是没有保留两位小数。网上的具体方法是这样的:

1
2
3
4
5
6
7
8
9
10
11
12

//分转换为元
var fen_yuan = function(val){
//toFixed来确定保留两位小数 因为除以100 所以都会整除
var str = (val/100).toFixed(2) + '';
var intSum = str.substring(0,str.indexOf(".")).replace( /\B(?=(?:\d{3})+$)/g, ',' );
//取到整数部分
var dot = str.substring(str.length,str.indexOf("."))
//取到小数部分
var ret = intSum + dot;
return ret;
}

如上代码,我给出了基本的注释,大家应该可以读懂,但是注意tofixed()这个函数会把小数点后面的部分进行四舍五入,所以不能得到精确结果。这个地方运用的因为是除以100,所以不存在不精确的问题,如果大家来使用的时候还是要参考当前的需求的。

3. 问题四

有些时候我们在这个页面获得了一些数据,但是我们在去往下一个页面的时候还是需要这些数据而下一个页面的接口没有返回这些数据的时候怎么办?

这时候就需要把我们需要的数据拼接到url当中,在到了下一个页面的时候,再把url中的参数分离出来,调用我们需要的一些参数。

分离url参数的方法贴在下面,供大家参考。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

var getQuery = function(){
var url=location.search;
var Request = {};
if(url.indexOf("?")!=-1)
{
var str = url.substr(1);
strs = str.split("&");
for(var i=0;i<strs.length;i++)
{
var _key = strs[i].split("=")[0];
Request[_key]=strs[i].split("=")[1];
}
}
return Request;
};

如上代码,我们把url?号部分后面的参数分离出来,组成一个对象,在需要哪个参数的时候,我们只要调用getQuery中对应的属性就可以了。


学习到的经验

1. 添加标识符

在写ajax的时候,在ajax的不同阶段,应该设置一个标识符来进行标识,以jqueryajax为例,比如:beforeSendsuccesscomplete等等不同的阶段,对发送ajax的状态来进行标识。

这个经验其实是这样的:我在设置下拉加载更多的时候,发现有的时候可能会发出多次请求,如果我们在程序里加上一个标识符,就可以避免这个问题的发生,如下代码:

1
2
3
4
5
6
7
8
9
10

beforeSend: function(){
loading = true;
},
success: function(data){
page += 1;
},
complete: function(){
loading = false;
}

如上代码这个只是举一个例子,并不是全部代码,逻辑大概是这样,当页面滑到底部,就发出一个请求请求page+1页的数据。如果我一次下拉发出多次请求的话,在success中的page就会累加多次,出现错误。如果我们添加了标识符后,当只有loading结束的时候才去发送下一次请求,所以当一些特殊情况比如网络不好的情况下,下拉了多次而ajax还没有发送成功的时候,是不会发送第二次ajax请求的。这样就能避免这个问题的产生。


2. 可以通过url把参数带到下一个页面

这个经验在上面的问题中已经说过了,而且我还听同事介绍了,其实这种方式是最常用的一种把参数传导下一个页面的办法,虽说这种办法显得url不够优雅。。。。。


3. 如果url所带的参数中有汉字怎么办

在我携带参数的时候,有的参数可能是汉字,而在参数带到下一个页面后,如果调用这个参数的话,会出现乱码类似于%E5%B7%A5%E4这样的。其实这个不是乱码,而是浏览器所做的encodeURI编码,而我们所要做的就是只要把它decodeURI解码后,我们就可以在下一个页面中正常的使用了。


4. handlebars helpers的学习

这个在上文中已经做了介绍,其实helper还能完成一些更复杂的逻辑,大家可以多试一试,比如我在遇到判断的类型多的时候就写了一个switchhelper

以上。