AngularJS - 簡單應用02 (ng-repeat, ng-show, ng-hide, ng-dbclick, ng-bind-template)

打鐵就要趁熱,
馬上再來一個應用範例來學習更多AngularJS的其他Directive,
這次要練習的範例是要完成一個簡單的動態新增物品存貨的列表,
這個範例所新增的的資料會僅在前端頁面顯示,不會與DB連線。
下面的範例會使用到ngRepeat, ngShow, ngHide, ngDblclick, ngBindTemplate
接著按照慣例先來接紹這幾個Directive的功能。

ngRepeat

ngRepeat的功能可以把它當作C#中的foreach迴圈,
將Collection中的所有物件巡覽過一次,
<ANY ng-repeat="{repeat_expression}">
   ...
</ANY>
repeat_expression為類似foreach迴圈內的表示式,
舉個例子來說,假設$scope裡有個itemList的集合,
那用ng-repeat時表示方法為ng-repeat="item in itemList",
在ng-repeat的區域裡就能夠使用item物件,
此外,repeat_expression有另一種表示方法,
直接尋覽資料集合,例如:(name, age) in {'A': 25, 'B': 26},
比較令人意外的是,AngularJS在1.2.1版以後就提供了ng-repeat-start,
類似ng-repeat的表示方法,不同的是使用ng-repeat-start與ng-repeat-end,
劃出要repeat的區段,
<ANY ng-repeat-start="{repeat_expression}">
  ...
</ANY>
<ANY>
  ...
</ANY>
...
<ANY ng-repeat-end>
  ...
<ANY>

ngShow

ngShow可以根據expression內的判斷式值來顯示元件,

若expression判斷式值為true則顯示,反之不顯示。
<ANY ng-show="{expression}">
   ...
</ANY>

ngHide

ngHide是與ngShow相反的directive,
兩個的用法都一樣,差別在於ngHide,
如果expression判斷式值為true則不顯示,反之則顯示

<ANY ng-hide="{expression}">
   ...
</ANY>

ngDbclick

ngDbclick從名稱看來就可以猜到它是處理滑鼠Double Click事件的Directive,
和JavaScriptOnClick事件類似,只要在在expression裡填入觸發的事件處理,
或呼叫Controller裡的Function。
<ANY ng-dblclick="{expression}">
   ...
</ANY>

ngBindTemplate

先前在有提到,要將ngModel值印出來需要用{{model}}的方式,
但如果當載入頁面時,AnguarJS的套件還沒Load進來,
HTML頁面顯示ngModel的部分就會變成{{model}},
我們不想讓使用者看到底層的東西,
這時候就要使用ngBindTemplate或ngCloak,
這兩個的功能在上述情況下,使用者不會看到{{model}}的字串,
相較之下,ngBindTemplate的彈性較好,
所以個人推薦使用ngBindTemplate,
ngBindTemplate使用方式如下:
<ANY ng-bind-template="{string}">
   ...
</ANY>

舉個例子, 假設我們設定:
<label ng-bind-template="Hello {{username}}"></label>,
以上執行結果會和<label>Hello {{username}}</label>一樣,
或者也可以將ng-bind-template想成C#中的Striing.Format()功能,
意思是建構一個字串Template。

以下程式碼為應用ngRepeatngShowngHidengDblclickngBindTemplate的範例:
index.html:
<!DOCTYPE html>
<html ng-app>
  <head>
    <link rel="stylesheet" href="style.css">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
  </head>
    <script src="script.js"></script>
  <body ng-controller="MyController">
    <span>
      <label></label>
      <input type="text" placeholder="Name" ng-model="Item.Name"/>
      <input type="text" placeholder="Count" ng-model="Item.Count"/>
      <input type="button" value="Add" ng-click="AddItem(Item)"/>
    </span><br/>
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Count</th>
        </tr>
        <tr ng-repeat="item in itemList">
          <td>
            <span ng-dblclick="item.isEdit = !item.isEdit">
              <label ng-bind-template="{{item.name}}" ng-show="!item.isEdit"></label>
              <input type="text" ng-model="item.name" ng-hide="!item.isEdit"/>
            </span>
          </td>
          <td>
            <span ng-dblclick="item.isEdit = !item.isEdit">
              <label ng-bind-template="{{item.count}}" ng-show="!item.isEdit" ng-dbclick="item.isEdit = !item.isEdit"></label>
              <input type="text" ng-model="item.count" ng-hide="!item.isEdit"/>
            </span>
          </td>
          <td ng-hide="!item.isEdit">
            <input type="button" value="Save" ng-click="SaveValue(item)"/>
          </td>
        </tr>
      </thead>
    </table>
  </body>
</html>


script.js:
function MyController($scope) {
  $scope.itemList = [];
  $scope.AddItem = function() {
    this.itemList.push({name: this.Item.Name, count: this.Item.Count, isEdit: false});
    this.Item = null;
  }
  $scope.SaveValue = function(item) {
    if(item.name !== '' && item.count !== '') {
      item.isEdit = false;
    }
  }
}

style.css:
table, th, td {
  border: 1px solid blue;
}

執行結果:

Name Count



留言