angularjs表單相關之封裝radio、select、filter
好了,廢話不多說開始整。
一、為什麼要這幾個一起說?
因為我在建立統一的filter時,就發現,哦~~原來還可以這麼搞,確實省了不少程式碼。當然你要是處女座的話,我覺得你可以分開寫,只要注入就好了。反正對於我來說都是自己寫的指令,就暫時放在一起嘍。
書歸正題,首先這個地方我覺得還少了checkbox,但是目前沒有實踐,等實踐完了再把這塊內容補上。
先說說大體思路,我們首先為我們需要的列舉來建一個factory,然後用這個factory來指導自定義的radio,select ,filter。當然,這只是我的一點淺見。
好了,下面說幹就幹。
二、實踐部分(我覺的直接上程式碼比較容易,然後再講)
1. 最開始我們先建一個module(這個沒什麼好講的)
2. 新建一個我們需要的factory<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公里,回來就睡覺了。結果本週忙的要死,今天才抽出空來把這些程式碼搞定。但是當時遇到的一些坑確實忘記了一點,以後會補充進來。