2014年7月27日 星期日

AngularJS:ng-repeat、KeyValueObject、join、customer filter with textfield、multiple ng-app



Search:
{{ title }}{{member.name}}→[{{member.skills.join('@')}} ]
{{ member.experience }}%

精簡版:http://jsbin.com/guvuq/18/edit

完整版:http://jsbin.com/mipar/11/edit

一、設計一個textfield用來過濾資料,將ng-model設定為query。

Search:<input ng-model="query" placeholder="Type to filter" />    
  <br />

二、controller設計

<script language="javascript">
var myApp = angular.module('myApp', ['RoleApp']);
function isCompared(key,values,query){
   //---------將key,value內容轉為string且小寫再行比較---------------//
   key = key.toString().toLowerCase();
   query = query.toString().toLowerCase(); 
   if (key.indexOf(query) != -1) return true;//若key中有搜尋值則代表找到
   //---------若values內中有包含搜尋值則代表已找到------------------//
   for (var data in values) {
       var text = values[data].toString().toLowerCase();
       if (text.indexOf(query) != -1) return true;
      
   }
  return false;//未找到
}
angular.module('filters',[])
  .filter('RoleFilter', function(){
    
    return function(input, query){
      if(!query) return input;
      var result = {};
      
      angular.forEach(input, function(friendData, friend){
        if(isCompared(friend,friendData,query))
          result[friend] = friendData;          
      });
      return result;
    };
  });
    
var RoleApp = angular.module('RoleApp',['filters'])
  .controller('RoleCtrl', function($scope) {
    $scope.members = {
  '神射手': {
   name: '迪文',
   importance: 5,
                        experience:98,
   skills: ['二連矢', '銳利射擊']
  },
  '騎士領主': {
   name: '賽依連',
                        importance: 5,
   experience:95,
   skills: ['狂擊', '艾斯敦攻擊']
  },
                '十字刺客': {
   name: '艾勒梅斯',
                        importance: 4,
   experience:95,
   skills: ['音速攻擊', '黑暗瞬間']
  },
                '魔導師': {
   name: '凱特莉娜',
                        importance: 4,
   experience:90,
   skills: ['暴風雪', '咖般塔音']
  },
                '神工匠': {
   name: '哈沃得',
                        importance: 3,
   experience:70,
   skills: ['大地之擊', '金錢攻擊']
  },
                '神官': {
   name: '瑪嘉雷特',
                        importance: 2,
   experience:60,
   skills: ['治癒術', '天使之怒']
  }
 };
  }); 
 RoleApp.filter('getLoopTimes', function() {//設定迴圈次數
  return function(input, total) {
    total = parseInt(total);
    for (var i=0; i<total; i++)
      input.push(i);
    return input;
  };
});

  </script>
(一)由於angularJS預設僅能存在一個ng-app,若要擴充則需要將主要的ng-app模組化,這一段是因應此blogger而設計,因發佈許多文章,故不可能再使用angularJS的時候只使用單一ng-app,故須加入下列程式碼,而一開始也必須加入一段。
1.var myApp = angular.module('myApp', []);//一開始
2.var myApp = angular.module('myApp', ['RoleApp']);//需使用新的app時
(二)自訂一個filter->getLoopTimes來傳入n,並增加n個空間。
RoleApp.filter('getLoopTimes', function() {//設定迴圈次數
  return function(input, total) {
    total = parseInt(total);
    for (var i=0; i&lt;total; i++)
      input.push(i);
    return input;
  };
});
(三)利用RoleApp實作controller功能並繫結filters(RoleFilter),且設定members內容,以物件方式存之以利而後使用foreach印出。
var RoleApp = angular.module('RoleApp',['filters'])//加入filter
  .controller('RoleCtrl', function($scope) {//實作controller
    $scope.members = {
  '神射手': {
   name: '迪文',
   importance: 5,
                        experience:98,
   skills: ['二連矢', '銳利射擊']
  },
  '騎士領主': {
   name: '賽依連',
                        importance: 5,
   experience:95,
   skills: ['狂擊', '艾斯敦攻擊']
  },
                '十字刺客': {
   name: '艾勒梅斯',
                        importance: 4,
   experience:95,
   skills: ['音速攻擊', '黑暗瞬間']
  },
                '魔導師': {
   name: '凱特莉娜',
                        importance: 4,
   experience:90,
   skills: ['暴風雪', '咖般塔音']
  },
                '神工匠': {
   name: '哈沃得',
                        importance: 3,
   experience:70,
   skills: ['大地之擊', '金錢攻擊']
  },
                '神官': {
   name: '瑪嘉雷特',
                        importance: 2,
   experience:60,
   skills: ['治癒術', '天使之怒']
  }
 };
  }); 
(四)實作RoleFilter,利用foreach整個members並使用isCompared函式來檢查textfield輸入的文字是否存在於members內,且加以過濾。
angular.module('filters',[])
  .filter('RoleFilter', function(){//自定義filter
    
    return function(input, query){
      if(!query) return input;
      var result = {};
      
      angular.forEach(input, function(friendData, friend){
        if(isCompared(friend,friendData,query))
          result[friend] = friendData;          
      });
      return result;
    };
  });
(五)實作isCompared函式,傳入key、values、query,運作原理主要是先檢查key是否包含query若否則檢查values內各個資料成員。
function isCompared(key,values,query){//檢查members內資料是否包含query字串
   //---------將key,value內容轉為string且小寫再行比較---------------//
   key = key.toString().toLowerCase();
   query = query.toString().toLowerCase(); 
   if (key.indexOf(query) != -1) return true;//若key中有搜尋值則代表找到
   //---------若values內中有包含搜尋值則代表已找到------------------//
   for (var data in values) {
       var text = values[data].toString().toLowerCase();
       if (text.indexOf(query) != -1) return true;
      
   }
  return false;//未找到
}

三、資料輸出

<div ng-controller="RoleCtrl" style="margin-top: 20px;">
<div ng-repeat="(title, member) in members|RoleFilter:query">
<div class="isa_info" style="background-color: #bde5f8; color: red; height: 35px; width: 100%;">
<a class="button red " href="https://www.blogger.com/blogger.g?blogID=5937314774695181933" style="border-radius: 15px; color: white; font-size: 24px; padding: 0px 0px;">
         <span ng-repeat="n in [] | getLoopTimes:member.importance">
                     ★
         </span>
     </a>
             {{ title }}{{member.name}}→[{{member.skills.join('@')}} ]
      <a class="button red " href="https://www.blogger.com/blogger.g?blogID=5937314774695181933" style="border-radius: 15px; color: white; font-size: 24px; padding: 0px 0px;">
         <span ng-repeat="n in [] | getLoopTimes:member.importance">
                     ★
         </span>
     </a>
   </div>
<div class="progress">
<span class="orange" style="width: {{ member.experience }}%;">{{ member.experience }}%</span>
   </div>
</div>
</div>
</div>
(一)將ng-controller設定為RoleCtrl。
<div ng-controller="RoleCtrl" style="margin-top: 20px;">
(二)使用ng-repeat將members內資料印出及使用自定義過濾器RoleFilter
<div ng-repeat="(title, member) in members|RoleFilter:query">
(三)以下程式碼則將members資料搭配自訂面板印出,而比較特別的是:ng-repeat="n in [] | getLoopTimes:member.importance",這一段主要利用上面controller所設計的getLoopTime過濾器並傳入member.importance(數字型態)參數來決定要印出多少個★,另外也設計processbar的css同樣透過參數傳入來決定長條進度。
<div class="isa_info" style="background-color: #bde5f8; color: red; height: 35px; width: 100%;">
<a class="button red " href="https://www.blogger.com/blogger.g?blogID=5937314774695181933" style="border-radius: 15px; color: white; font-size: 24px; padding: 0px 0px;">
         <span ng-repeat="n in [] | getLoopTimes:member.importance">
                     ★
         </span>
     </a>
             {{ title }}{{member.name}}[{{member.skills.join('@')}} ]
      <a class="button red " href="https://www.blogger.com/blogger.g?blogID=5937314774695181933" style="border-radius: 15px; color: white; font-size: 24px; padding: 0px 0px;">
         <span ng-repeat="n in [] | getLoopTimes:member.importance">
                     ★
         </span>
     </a>
   </div>
<div class="progress">
<span class="orange" style="width: {{ member.experience }}%;">{{ member.experience }}%</span>
   </div>

四、完整程式碼-部落格版(多個app處理方式)

<script language="javascript">
var myApp = angular.module('myApp', ['RoleApp']);
function isCompared(key,values,query){//檢查members內資料是否包含query字串
   //---------將key,value內容轉為string且小寫再行比較---------------//
   key = key.toString().toLowerCase();
   query = query.toString().toLowerCase(); 
   if (key.indexOf(query) != -1) return true;//若key中有搜尋值則代表找到
   //---------若values內中有包含搜尋值則代表已找到------------------//
   for (var data in values) {
       var text = values[data].toString().toLowerCase();
       if (text.indexOf(query) != -1) return true;
      
   }
  return false;//未找到
}
angular.module('filters',[])
  .filter('RoleFilter', function(){//自定義filter
    
    return function(input, query){
      if(!query) return input;
      var result = {};
      
      angular.forEach(input, function(friendData, friend){
        if(isCompared(friend,friendData,query))
          result[friend] = friendData;          
      });
      return result;
    };
  });
    
var RoleApp = angular.module('RoleApp',['filters'])//加入filter
  .controller('RoleCtrl', function($scope) {//實作controller
    $scope.members = {
  '神射手': {
   name: '迪文',
   importance: 5,
                        experience:98,
   skills: ['二連矢', '銳利射擊']
  },
  '騎士領主': {
   name: '賽依連',
                        importance: 5,
   experience:95,
   skills: ['狂擊', '艾斯敦攻擊']
  },
                '十字刺客': {
   name: '艾勒梅斯',
                        importance: 4,
   experience:95,
   skills: ['音速攻擊', '黑暗瞬間']
  },
                '魔導師': {
   name: '凱特莉娜',
                        importance: 4,
   experience:90,
   skills: ['暴風雪', '咖般塔音']
  },
                '神工匠': {
   name: '哈沃得',
                        importance: 3,
   experience:70,
   skills: ['大地之擊', '金錢攻擊']
  },
                '神官': {
   name: '瑪嘉雷特',
                        importance: 2,
   experience:60,
   skills: ['治癒術', '天使之怒']
  }
 };
  }); 
 RoleApp.filter('getLoopTimes', function() {//設定迴圈次數
  return function(input, total) {
    total = parseInt(total);
    for (var i=0; i<total; i++)
      input.push(i);
    return input;
  };
});

  </script>

<br />
<div id="RoleDiv">
Search:<input ng-model="query" placeholder="Type to filter" />    
  <br />
<div ng-controller="RoleCtrl" style="margin-top: 20px;">
<div ng-repeat="(title, member) in members|RoleFilter:query">
<div class="isa_info" style="background-color: #bde5f8; color: red; height: 35px; width: 100%;">
<a class="button red " href="https://www.blogger.com/blogger.g?blogID=5937314774695181933" style="border-radius: 15px; color: white; font-size: 24px; padding: 0px 0px;">
         <span ng-repeat="n in [] | getLoopTimes:member.importance">
                     ★
         </span>
     </a>
             {{ title }}{{member.name}}→[{{member.skills.join('@')}} ]
      <a class="button red " href="https://www.blogger.com/blogger.g?blogID=5937314774695181933" style="border-radius: 15px; color: white; font-size: 24px; padding: 0px 0px;">
         <span ng-repeat="n in [] | getLoopTimes:member.importance">
                     ★
         </span>
     </a>
   </div>
<div class="progress">
<span class="orange" style="width: {{ member.experience }}%;">{{ member.experience }}%</span>
   </div>
</div>
</div>
</div>

五、完整程式碼-單一網頁版

<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js"></script>
  <link rel="stylesheet" href="https://aaad366b26125175724dd9c91cbade0cd1509dd0.googledrive.com/host/0B4GSVRY43FEXeUVOTlZNR0xqUkk/css/barAndInfo.css">
  <link rel="stylesheet" href="https://aaad366b26125175724dd9c91cbade0cd1509dd0.googledrive.com/host/0B4GSVRY43FEXeUVOTlZNR0xqUkk/css/button.css">
  
  <script language="javascript">
function isCompared(key,values,query){
   //---------將key,value內容轉為string且小寫再行比較---------------//
   key = key.toString().toLowerCase();
   query = query.toString().toLowerCase(); 
   if (key.indexOf(query) != -1) return true;//若key中有搜尋值則代表找到
   //---------若values內中有包含搜尋值則代表已找到------------------//
   for (var data in values) {
       var text = values[data].toString().toLowerCase();
       if (text.indexOf(query) != -1) return true;
      
   }
  return false;//未找到
}

angular.module('filters',[])
  .filter('RoleFilter', function(){
    
    return function(input, query){
      if(!query) return input;
      var result = {};
      
      angular.forEach(input, function(friendData, friend){
        if(isCompared(friend,friendData,query))
          result[friend] = friendData;          
      });
      return result;
    };
  });
    
var RoleApp = angular.module('app',['filters'])
  .controller('RoleCtrl', function($scope) {
     $scope.members = {
  '神射手': {
   name: '迪文',
   importance: 5,
            experience:98,
   skills: ['二連矢', '銳利射擊']
  },
  '騎士領主': {
   name: '賽依連',
            importance: 5,
   experience:95,
   skills: ['狂擊', '艾斯敦攻擊']
  },
        '十字刺客': {
   name: '艾勒梅斯',
            importance: 4,
   experience:95,
   skills: ['音速攻擊', '黑暗瞬間']
  },
       '魔導師': {
   name: '凱特莉娜',
            importance: 4,
   experience:90,
   skills: ['暴風雪', '咖般塔音']
  },
        '神工匠': {
   name: '哈沃得',
            importance: 3,
   experience:70,
   skills: ['大地之擊', '金錢攻擊']
  },
        '神官': {
   name: '瑪嘉雷特',
            importance: 2,
   experience:60,
   skills: ['治癒術', '天使之怒']
  }
 };
  }); 
  RoleApp.filter('getLoopTimes', function() {
  return function(input, total) {
    total = parseInt(total);
    for (var i=0; i<total; i++)
      input.push(i);
    return input;
  };
});
  </script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
<div ng-app='app'>
  Search:<input placeholder="Type to filter" ng-model="query">    
  <div style="margin-top:20px;" ng-controller="RoleCtrl" >
     <div ng-repeat="(title, member) in members|RoleFilter:query">
     <div  class="isa_info" style="width:100%;background-color:  #BDE5F8;height: 35px;color: #333;">
    <a href="" class="button red " target="_blank" style=" padding: 0px 0px;font-size: 24px;color:#FFF;border-radius: 15px;">
                <span ng-repeat="n in [] | getLoopTimes:member.importance">
                     ★
                </span>

          </a>
             {{ title }}{{member.name}}→[{{member.skills.join(', ')}} ]
           <a href="" class="button red " target="_blank" style=" padding: 0px 0px;font-size: 24px;color:#FFF;border-radius: 15px;">
                <span ng-repeat="n in [] | getLoopTimes:member.importance">
                     ★
                </span>

          </a>
     </div>
     <div class="progress" >
           <span class="orange" style="width: {{ member.experience }}%;"><span>{{ member.experience }}%</span>
     </div>
      </div>
   </div> 
</div>
</body>
</html>

沒有留言:

張貼留言