好了,废话不多说开始整。
一、为什么要这几个一起说?
因为我在创建统一的filter时,就发现,哦~~原来还可以这么搞,确实省了不少代码。当然你要是处女座的话,我觉得你可以分开写,只要注入就好了。反正对于我来说都是自己写的指令,就暂时放在一起喽。
书归正题,首先这个地方我觉得还少了checkbox,但是目前没有实践,等实践完了再把这块内容补上。
先说说大体思路,我们首先为我们需要的枚举来建一个factory,然后用这个factory来指导自定义的radio,select ,filter。当然,这只是我的一点浅见。
好了,下面说干就干。
二、实践部分(我觉的直接上代码比较容易,然后再讲)
1. 最开始我们先建一个module(这个没什么好讲的)
<span style="font-size:18px;">var allInput = angular.module('allInput', []);</span>
<span style="font-size:18px;">allInput.factory('$status', function(){
<span style="white-space:pre"> </span>var status = {
<span style="white-space:pre"> </span>0: '审核拒绝',
<span style="white-space:pre"> </span>1: '审核通过', //我故意省略2
<span style="white-space:pre"> </span>3: '未审核',
<span style="white-space:pre"> </span>4: '重新提交审核',
<span style="white-space:pre"> </span>'hehe': '已封禁' //如果后端的枚举是hehe或者什么的我们应该也能应付
<span style="white-space:pre"> </span>};
<span style="white-space:pre"> </span>return status;
});</span>
<span style="font-size:18px;">
</span>
<span style="font-size:18px;">//这个地方是两个控件都要用到的公共配置</span>
<span style="font-size:18px;"></span><pre name="code" class="javascript">allInput.factory('$defaultOption', function($status){
return {
status: {
data: $status
},
//这个下面还可以填充好多类似于上面的东西
removeDiff: function(a, b){
//这块的主要意思是b里面有的东西就要替换a
if(a == null){
return b;
}
if(b == null){
return a;
}
//如果都没有空,就返回a配置
for (i in a){
if(i in b){
a[i] = b[i];
}
}
return a;
}
};
});
好了,解释一下代码,就是建一个factory,然后将status这个数组,用$status来表示,其实就是很简单!!!前面的索引数字代表的是枚举值,后面代表的是含义,当然,我们也可以写成英文或者什么,并不影响什么。比如说已封禁那个。中间的2是我故意省去的,为了大家看了可以更好的举一反三(或许对于程序员这种高智商的动物并没有什么卵用,anyway)
后面这个地方是我又思考了一下,粘贴在上面的,因为可以提出来共同使用
3. 新建一个filter
allInput.filter('status', function($status){
return function(input){
return input in $status ? $status[input] : '未知';
}
});
好了,一个合理合法的filter就这么建好了,是不是特别的开心?是不是特别的简单,当然,我们也可以不用引入$status,我们只要把$status那一坨放在filter的回调函数里就可以啦,呵呵呵
4. 建一个统一的select控件
<span style="font-size:18px;">allInput.directive('selectInput', function($defaultOption){</span><span style="font-size:18px;">
return {
restrict: 'AE',
<span style="white-space:pre"> </span>replace: ture,
scope: {
ngType: '@', //这个地方是为了说明这个控件到底要显示哪个枚举(我们可能有多个枚举)
myConfig: '='//这个地方可以传入一些我们自定义的配置,这样我们就可以不用局限于他自己的type了
},
//我这里写到controller纯粹是因为他简单,第二一点,我也没有真正理解,为什么放入link是最佳实践
//这里的$selectOption 是我们要为了自定义的方法而用的,看到这里不明白先不要着急
controller: function($scope, $defaultOption){</span><span style="font-size:18px;">
//这个地方是要把真实的值传给option做渲染
$scope.option = $defaultOption.removeDiff($defaultOption[$scope.ngType], $scope.myConfig);
},
templateUrl: 'select.html'
};
});</span>
<span style="font-size:18px;">
//最后的最后再加一个模板,就完事儿了
allInput.run(function($templateCache){
$templateCache.put('select.html',
' \
<select \
ng-options = "key as value for (key, value) in option.data"> \
</select> \
'
);
});</span>
<span style="font-size:18px;">引用实例 <select-input ng-type = "status" ng-model = "xxx" /></span>
做到这个地方,基本上我们我们一个select 控件就完成了, 是不是特别的简单,想一想,每次只要添加一个factory就可以用一行代码来创建一个下拉框。反正我觉得真的是大大提高了工作效率。
5. 创建一个统一的radio控件
<span style="font-size:18px;">// 这个要提前写,写这个控件的时候,我真的遇到了不少麻烦,所以只能进行一丢丢的dom操作,还希望哪个厉害的大哥可以指点我一下
//然后开始撸代码
allInput.directive('radioInput', function($defaultOption){
return {
restrict: 'AE',
replace: true,
scope: {
ngType: '@', //这俩跟上面一样
myConfig: '='
},
//这个地方因为是写demo,我是犯个懒,用之前select的
controller: function($scope, $defaultOption){
$scope.option = $defaultOption.removeDiff($defaultOption[$scope.ngType], $scope.myConfig);
},
templateUrl: 'radio.html'
};
});
//这里也写一个模板
allInput.run(function($templateCache){
//这个地方是我最头疼的,因为不能同步ng-model,所以我写了一个指令来进行dom操作
$templateCache.put('radio.html',
'<input ng-repeat = "(key, value) in option.data" radio-to-name type = "radio" value = "{{key}}" radio-value = "{{value}}">'
);
});
//这个地方就是重点,我目前为止还不知道怎么处理,所以只能写一个dom来操作,有大神可以指点我,呵呵
allInput.directive('radioToName', function(){
return {
restrict: 'A',
terminal: true, //这个地方指定优先级最低,要让ng-repeat指令完成之后才可以执行
link: function(scope, ele, attr){
ele.after('' + attr.radioValue + '');
}
};
});</span>
三 实践效果与坑
1. 实践效果
到了这一步,基本上没什么好讲的了,大家就可以放开了用了,下面写几个应用实例
效果预览:http://4.pandaliu.sinaapp.com/
代码:https://github.com/sd142400/angular-input
2. 坑
基本上上面的代码没有看什么资料,完全就是按照之前我做项目的经验手打了一遍,但是在用的时候大概出现了以下几个坑
2.1 ng-options 这种命令,需要添加ng-model才可以生效
2.2 radio 这个控件,如果是直接$scope.xxx这个作用域会变成子作用域下,所以要用$scope.model.xxx来解决这个问题。当然,model也可以换成别的什么
以上就是我的一些经验,欢迎大神来指正。这篇文章是上周日写的,写到最后调试不了,我就去跑了10公里,回来就睡觉了。结果本周忙的要死,今天才抽出空来把这些代码搞定。但是当时遇到的一些坑确实忘记了一点,以后会补充进来。