首页 > 开发 > 前端 > 正文

Angular复杂页面之劲爆体验

2016-07-25 21:30:00  来源:慕课网
  最近被一个逻辑很恶心的项目折腾的死去活来,有必要在这里吐槽一下。因为我感觉到整个人都不好了,我都开始怀疑人生,怀疑智商了。
  项目虐我千百遍,我带项目如初恋
  这句话绝对是骗人的,上一张媳妇的玉手照,在这炎炎夏日清热解暑。

遇到问题还得解决,即使恶心,吐完了还是要继续的吃的。又不是SHI,没那么可怕的。
  开始正题,先来看看需求。
  说现在有一个页面,ios和安卓客户端还有微信内显示的内容不一样,页面内有一个下拉选择框,下拉选改变,页面中的内容也不一样,当然这样说太抽象了,上一张图看看。
  
  嗯,问题就是上面这样了,上图中没有说明每种平台的充值面额和面额单位是不一样,这里就不说样式什么的也不一样了。
  
  当然,这都是表象,所有复杂的问题,都是要慢慢解决,一个一个解决。首先是设备环境判断,这个很简单,网上有很多设备判断的代码段,我这里有一段。
//识别设备var system = function(name) { var u = navigator.userAgent.toLocaleLowerCase(), system = {}; ['mobile', 'iphone', 'android', 'micromessenger'].forEach(function(name) { system[name] = new RegExp(name, 'g').test(u); }); system.weixin = system.micromessenger; return name === undefined ? system : system[name];};  然后根据设备拉取不同的页面数据,因为上图中的下拉框和面额选这都是后台的数据,页面中的静态html其实很少。
if(system().weixin) { //微信内打开 $scope.weixin = true; if(system().iphone) { $scope.getPage("weixin"); $scope.ios = true; } else { document.body.innerHTML = ""; location.href = "http://www.youximao.tv/wap/index.html"; } } else { //应用内打开 $scope.weixin = false; if(system().iphone) { //iphone内打开 $scope.getPage("iphone"); $scope.ios = true; } else { $scope.getPage("android"); //android内打开 $scope.ios = false; } }  这样基本就解决了不同设备环境的数据匹配问题了,当然现在还有数据问题,我们先来看下后端过来的数据是什么样的。
{ "code": "000", "data": { "defChoose": 401, "categoryList": [ { "categoryName": "九游", "categoryId": 401, "categoryExt": { "ctime": 1467788595, "extName": "U点", "goodsCategoryId": 401, "isDelete": 1, "prompt": "", "proportion": 10, "utime": 1467788595 }, "denominations": [ { "ctime": 1467624031, "denominationCategoryId": 401, "denominationId": 6, "goodsCategoryId": 12, "goodsTypeId": 3, "isDelete": 1, "isEnable": 1, "name": "50U点", "num": 50.00, "price": 48.00, "utime": 1467683017 }, { "ctime": 1467624440, "denominationCategoryId": 401, "denominationId": 7, "goodsCategoryId": 11, "goodsTypeId": 3, "isDelete": 1, "isEnable": 1, "name": "30U点", "num": 30.00, "price": 30.00, "utime": 1467684863 } ] } ] "catPoint": 4410 }, "message": "success"}  上面的数据list基本都只取了一个值,这样的数据拿过来,其实是有点复杂的,我们需要从中间提取出有用数据,现在我应该比较庆幸选择angular来搭建这个页面了。
<div class="form-group margin-top-4"> <label class="form-lable" for="plat">充值平台</label> <div class="select-warp" name="plat"> <select class="select" ng-model="plat" ng-options="plat as plat.categoryName for plat in page.categoryList" ng-change="changePlat()"></select> </div></div><p class="message"><span ng-show="plat.categoryName == '百度'">代金券有效期7天</span</p>  这样看起来是不是很方便,当然还有一个百度平台的另类。
<!--baidu 选择百度的时候显示--> <div class="baidu" ng-show="plat.categoryName == '百度'"> <div class="form-group"> <label class="form-lable">账号类型</label> <div class="radio-type"> <input type="radio" name="type" value="1" ng-model="formData.type" /> <span>百度账号</span> </div> <div class="radio-type"> <input type="radio" name="type" value="2" ng-model="formData.type" /> <span>多酷账号</span> </div> </div> <div class="form-group margin-top-4"> <label class="form-lable" for="game">游戏名称</label> <div class="input-warp"> <input class="input" type="text" name="game" placeholder="请输入游戏名称" ng-model="formData.game" ng-blur="validateGame()" /> </div> </div> <p class="message"><span ng-show="showMsg.game">请输入游戏名称</span></p> </div> <!--/baidu-->  面额选择部分
<!--choose-warp--> <div class="choose-warp"> <div class="choose"> <div class="radio-warp" ng-repeat="item in plat.denominations"> <input type="radio" name="denominationId" value="{{item.denominationId}}" ng-model="formData.denominationId" /> <button>{{item.num + plat.categoryExt.extName}}</button> </div> </div></div><!--/choose-warp-->  其实整个页面都是围绕着plat的选择,而变化的,所以js部分的逻辑只要围绕着plat的变化写就可以了。
$scope.changePlat = function() { $scope.formData.account = ""; //重置表单 $scope.formData.game = ""; //重置表单 $scope.showMsg.paybtn = true; //默认选择面额 $scope.formData.denominationId = $scope.plat.denominations[0].denominationId; switch($scope.plat.categoryName) { case "九游": $scope.placeholder = "手机号或UC号"; $scope.validateAccount = validateNum; break; case "百度": $scope.placeholder = "手机/邮箱/用户名"; $scope.validateAccount = validateLength; break; case "360": $scope.placeholder = "邮箱"; $scope.validateAccount = validateEmail; break; case "腾讯": $scope.placeholder = "QQ号码"; $scope.validateAccount = validateNum; break; default: $scope.placeholder = "邮箱"; $scope.validateAccount = validateEmail; break; } }  当然这里只是一部分功能的实现,关于支付按钮,弹出框的显示,按钮可否点击,不同设备显示不同的按钮等。
  以上都是装X部分,给你们一点小彩蛋。
  
  右侧开关按钮的纯css写法,input可以直接取值,配合angular很完美。
<div class="checkbox"> <input type="checkbox" name="remberAccount" ng-model="remberAccount" ng-change="isRember()" /> <span></span></div>  非常简单的页面结构,重要的部分是CSS
.checkbox { width: .8rem; height: .6rem; position: relative;}.checkbox input { position: absolute; width: 100%; height: 100%; opacity: 0; z-index: 10;}.checkbox span { box-sizing: content-box; position: absolute; display: block; width: .8rem; height: .4rem; top: .1rem; border: 1px solid #EEE; background: #FFF; border-radius: .4rem; -webkit-transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out;}.checkbox input+span:after { position: absolute; box-sizing: border-box; content: ""; right: .4rem; width: .4rem; height: .4rem; border: 1px solid transparent; box-shadow: 0 0 .05rem rgba(0, 0, 0, .5); background: #FFF; border-radius: .4rem; -webkit-transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out;}.checkbox input:checked+span { background: #FFD800;}.checkbox input:checked+span:after { right: 0;}  感觉文章有点标题党,干货太少了,可能是懒了,也可能是很多方案是思路上的,代码不能不能表述,不过有问题还是希望可以找我一起探讨,如果喜欢就点个赞吧。