關於AngularJs資料遞迴呈現的實現的幾種方式
阿新 • • 發佈:2019-02-18
在實踐中,常常會有資料結構一致但深度不確定的資料。而通常情況下,對資料的處理會用到遞迴的方式。例如網站的無限級分類的展現,分類資料結構:
複製- var cate =[
- {
- cateId:1,
- cateName:'前端技術',
- child:[
- {
- cateId:4,
- cateName:'JavaScript'
- },
- ...
- ]
- },
- {
- cate:2,
- cateName:'後端技術',
- child:[
- {
- cateId:3,
- cateName
- child:[
- {
- cateId:6,
- cateName:'ThinkPHP'
- },
- ...
- ]
- }
- ]
- }
- ];
用jq常常通過如下方式實現,示例程式碼如下:
複製- /**
- * * 解析模板檔案
- * @param template 模板字串
- * @param scope 模板作用域
- * return [string] 解析過後的字串
- */
- function templateParse(template, scope){
- if(typeoftemplate!="string"
- returntemplate.replace(/\{\w+\}/gi,function(matchs){
- var returns = scope[matchs.replace(/(\{)|(\})/g,"")];
- return(returns +"")=="undefined"?"": returns;
- });
- }
- /**
- * 解析並插入分類
- */
- $('#category').append(function(){
- vartemplate='<a href="{cateId}.html">{cateName}</a>';
- var ret =(function(c){
- if(!c ||!
- var ret ='<ul>';
- for(var i =0, j = c.length; i < j; i++){
- ret +='<li>';
- ret += templateParse(template, c[i]);
- ret += arguments.callee(c[i].child);
- ret +='</li>';
- }
- return(ret +'</ul>');
- })(cate);
- return ret;
- });
angularJs中基於模板遞迴的實現
同樣的原理,可以通過組合angularJs內建的ng-include
、ng-init
來達到遞迴的效果,示例模板如下:
- <scriptid="recursion"type="text/ng-template">
- <li ng-repeat="item in cate">
- <a href="{{item.cateId}}">{{item.cateName}}</a>
- <ul ng-if="item.child.length" ng-include="'recursion'" ng-init="cate=item.child"></ul>
- </li>
- </script>
呼叫方式如下:
複製- <divng-app="demo">
- <divng-controller="demo">
- <ulng-include="'recursion'"></ul>
- </div>
- </div>
基於指令遞迴的實現
同樣的道理,在指令中,咱們可以這麼來幹(內容參考自angular-recursion):
複製- angular.module('demo').directive('recursion',function($compile){
- function cpl(element, link){
- // Normalize the link parameter
- if(angular.isFunction(link)){
- link ={ post: link };
- }
- // Break the recursion loop by removing the contents
- var contents = element.contents().remove();
- var compiledContents;
- return{
- pre:(link && link.pre)? link.pre :null,
- /**
- * Compiles and re-adds the contents
- */
- post:function(scope, element){
- // Compile the contents
- if(!compiledContents){
- compiledContents = $compile(contents);
- }
- // Re-add the compiled contents to the element
- compiledContents(scope,function(clone){
- element.append(clone);
- });
- // Call the post-linking function, if any
- if(link && link.post){
- link.post.apply(null, arguments);
- }
- }
- };
- }
- return{
- restrict:'A',
- scope:{recursion:'='},
- template:'<li ng-repeat="item in recursion">\
- <a href="{{item.cateId}}.html">{{item.cateName}}</a>\
- <ul recursion="item.child">\
- </ul>\
- </li>',
- compile:function(element){
- return cpl(element,function(scope, iElement, iAttrs, controller, transcludeFn){
- // Define your normal link function here.
- // Alternative: instead of passing a function,
- // you can also pass an object with
- // a 'pre'- and 'post'-link function.
- });
- }
- };
- });
關於recursion指令
以上兩種方式實現與模板耦合的過於緊密,有沒有辦法可以像如下的方式來使用呢?(未完,等續)
複製- <ulrecursion="cate">
- <ling-repeat="item in cate">
- <ahref="{{item.cateId}}">{{item.cateName}}</a>
- <ulrecursion-child='item.child'></ul>
- </li>
- </ul>
源引:http://www.lyblog.net/detail/596.html