外挂式插件编程思路【敏捷框架篇】(9)
有了外挂式思维基础,开始涉及框架。个人理解,所谓框架就是自己研究一些习惯、一些风格,出于某个目的(如快速开发),而设计并开发出的一套生产工具。
我这里对框架的需求主要是两点
1、快。为了减少开发的工作时间。
2、简。是简化开发过程、简化开发思想,与大部分人理解的代码简洁是两回事。以前一个前辈跟我说过一句话,代码写得好不代表真的好,代码写得结构简单别人看得到才好。很多时候写4行代码比写1行代码好,因为有的时候方便阅读更重要。
框架起步,先定义一下自己的标签,我这里就用 zs(杂烧)
如:<zs zs-type="select" zs-option="option" zs-model="form.age" zs-change="age_change" zs-title="选择年龄" zs-placeholder="请选择"></zs>
下面代码,讲解思路,有点乱,非最终代码
【index.html】
<!DOCTYPE html>
<html ng-app="myApp" ng-controller="myhtml">
<head>
<meta charset="utf-8" />
<title>外挂式插件编程思路(敏捷框架篇)</title>
<script src="jquery.min.js"></script>
<script src="angular.min.js"></script>
<script src="app.js"></script>
<link rel="stylesheet" href="css/layui.css" media="all">
</head>
<body>
<form class="layui-form">
<!-- 框架需要有自定义的语法 -->
<zs zs-type="select" zs-option="option" zs-model="form.age" zs-change="age_change" zs-title="选择年龄" zs-placeholder="请选择"></zs>
</form>
<select ng-model="form.age">
<option value="" >请选择</option>
<option ng-repeat="x in option" value="{{x.value}}" ng-selected="form.age==x.value">{{x.text}}</option>
</select>
<script>
function load_select()
{
//所有select的渲染对象
app.$scope.render_select={
data:{},
open:function(id)
{
console.log('open');
if(!app.$scope.render_select.data[id].open)
{
app.$scope.render_select.data[id].open=true;
}else{
app.$scope.render_select.data[id].open=false;
}
},
select:function(id,obj)
{
console.log('select',id);
console.log(obj);
let this_model=app.$scope.render_select.data[id].model;
let this_change=app.$scope.render_select.data[id].change;
if(this_change)
{
let eval_change=`
if(obj.value != app.$scope.${this_model})
{
if(app.$scope.${this_change}) app.$scope.${this_change}(obj.value);
}
`;
console.log(eval_change);
eval(eval_change);
}
let eval_model=`app.$scope.${this_model}=obj.value;`;
eval(eval_model);
console.log(eval_model);
app.$scope.render_select.data[id].open=false;
},
show_text(option,value)
{
var text='';
for(var i in option)
{
if(option[i].value==value)
{
text=option[i].text;
break;
}
}
return text;
}
};
$('zs[zs-type="select"]').each(function(){
var $this=$(this);
var this_model=$this.attr("zs-model");
var this_option=$this.attr("zs-option");
var this_change=$this.attr("zs-change");
var this_title=$this.attr("zs-title");
var this_placeholder=$this.attr("zs-placeholder");
var this_id=(new Date()).valueOf()+'_'+Math.random();
//当前select的渲染对象
app.$scope.render_select.data[this_id]={
open:false,
model:this_model,
change:this_change
};
var this_select_html=`
<div class="layui-form-item" id="${this_id}">
<label class="layui-form-label">${this_title}</label>
<div class="layui-input-block">
<div class="layui-unselect layui-form-select {{render_select.data['${this_id}'].open==true ? 'layui-form-selected' : ''}}">
<div class="layui-select-title" ng-click="render_select.open('${this_id}')">
<input type="text" placeholder="${this_placeholder}" ng-attr-value="{{render_select.show_text(${this_option},${this_model})}}" readonly="" class="layui-input layui-unselect">
<i class="layui-edge"></i>
</div>
<dl class="layui-anim layui-anim-upbit" style="">
<dd lay-value="" class="layui-select-tips">${this_placeholder}</dd>
<dd lay-value="{{select_option.text.value}}" class="{{${this_model}==select_option.value ? 'layui-this' : ''}}" ng-repeat="select_option in ${this_option}" ng-click="render_select.select('${this_id}',select_option)">{{select_option.text}}</dd>
</dl>
</div>
</div>
</div>
`;
$this.before(app.html(this_select_html));
$this.remove();
});
app.update();
}
//框架的 标签功能 解析demo
//<zs zs-type="select" zs-option="option" zs-model="form.age" zs-change="age_change" zs-title="请选择您的年龄" zs-placeholder="请选择"></zs>
var app=ng_app();
app.init(function()
{
//tab标签相关
app.$scope.form={
age:''
};
app.$scope.option=[
{value:'1',text:'10岁及以下'},
{value:'2',text:'11-15岁'},
{value:'3',text:'1-20岁'},
{value:'4',text:'21-30岁以下'},
{value:'5',text:'31岁及以上'},
];
app.$scope.age_change=function(option)
{
console.error('选择了年龄');
console.log(option);
}
load_select();
app.update();//页面渲染
});
</script>
</body>
</html>【app.js】
function ng_app()
{
var MyApp=
{
app:null,
init:function(back)
{
console.log('init');
var me=this;
var app = angular.module('myApp',[]);
app.controller("myhtml",function($scope, $http,$window,$compile)
{
me.$scope=$scope;
me.$http=$http;
me.$window=$window;
me.$compile=$compile;
back();
});
this.app=app;
}
//更新模板渲染 优化ng频繁更新有报错,这里加1毫秒延迟 避免报错
,update:function(){
var me=this;
setTimeout(function(){
try{
me.$scope.$apply();
}catch(e){}
},1);
},
//配合jq使用,jq后的模板,重新渲染
html:function(html)
{
var that=this;
try{
var result=that.$compile(html)(that.$scope);
if(result.selector)//假设存在 this_tpl_new.selector 则认为ng变量不存在失败了
{
//console.error(this_tpl_new.selector);
var result=html;
}
}catch(e){
var result=html;
}
return result;
},
new:function(){
return this;
}
}
var result=MyApp.new();
return result;
};css用的layui,这里也是模仿layui的select,与原生的select双向绑定,非常完美。





