天天看點

AngularJS 問題&解決 | 技巧

目錄:

()檔案類型的input添加ng-model,選擇檔案之後在controller裡面擷取為undefined。

()想讓多個<tr>為一組進行repeat

()在較慢裝置上避免angular的内聯模版表達式對使用者可見。

()ng-switch用法

()在ng-repeat 中使用ng-hide或ng-if

()使用ng-href設定a标簽的href

()select中ng-options 用法

()directive 傳回對象用法
           

一、給檔案類型的input添加

ng-model

,選擇檔案之後在controller裡面擷取為undefined。

示例:

在controller裡面調用

$scope.vm.uploadme

值為

undefined

解決方法:

I created a workaround with directive:

.directive("fileread", [function () {
    return {
        scope: {
            fileread: "="
        },
        link: function (scope, element, attributes) {
            element.bind("change", function (changeEvent) {
                var reader = new FileReader();
                reader.onload = function (loadEvent) {
                    scope.$apply(function () {
                        scope.fileread = loadEvent.target.result;
                    });
                }
                reader.readAsDataURL(changeEvent.target.files[]);
            });
        }
    }
}]);
           

And the input tag becomes:

二、想讓多個為一組進行repeat

比如三個tr為一個單元進行循環,因為tr外層不能再嵌一個标簽來使用ng-repeat,是以可以使用

<table class="table">
    <tbody>
    <tr ng-repeat-start="item in todos">
      <td> This is item {{$index}}</td>
    </tr>
    <tr>
      <td>The action is : {{item.action}}</td>
    </tr>
    <tr ng-repeat-end>
      <td>Item {{$index}} is {{item.complete ? '' : "not"}} complete</td>
    </tr>
    </tbody>
  </table>
           

将ng-repeat-start和ng-repeat-end之間的元素進行重複。

三、在較慢裝置上避免angular的内聯模版表達式對使用者可見。

解決方法:

①使用ng-bind指令(不推薦)

②使用ng-cloak指令,放在包含有模版表達式的文檔部分。

<div ng-clock>
...
</div>
           

四、

ng-switch

用法

<div ng-switch on="data.mode">

    <div ng-switch-when="Table">
      <table class="table">
        <thead>
        <tr>
          <th>#</th>
          <th>Action</th>
          <th>Done</th>
        </tr>
        </thead>
        <tr ng-repeat="item in todos" ng-class="$odd ? 'odd' : 'even'">
          <td>{{ $index + 1 }}</td>
          <td ng-repeat="prop in item">{{ prop }}</td>
        </tr>
      </table>
    </div>

    <div ng-switch-when="List">
      <ol>
        <li ng-repeat="item in todos">
          {{item.action}}<span ng-if="item.complete"> ( Done ) </span>
        </li>
      </ol>
    </div>

    <!-- 預設 -->
    <div ng-switch-default>
      Select another options to display a layout
    </div>
  </div>
           

ng-switch

使用on指定表達式。

data.mode

取值為Table、List、None,根據使用者輸入切換視圖。

五、在

ng-repeat

中使用

ng-hide

ng-if

對表格使用Bootstrap的table-striped樣式,但需要根據一些條件隐藏某些行,當使用ng-hide時,可能會造成條紋狀不間隔。

<table class="table table-striped">
    <thead>
        ...
    </thead>
    <tr ng-repeat="item in todos" ng-hide="item.complete">
        ...
    </tr>
</table>
           

但是将

ng-hide

換為

ng-if

會報錯。

解決方案:

使用過濾器。

六、使用

ng-href

設定a标簽的href

與之相同的還有img元素的

ng-src

ng-srcset

七、select中

ng-options

用法

options="item.id as item.action for item in todos"

代表

<ng-model 使用的值>

as

<option 中顯示的值>

for

<變量名>

in

<數組>

例:

<!-- HTML -->
<select ng-options="item.id as item.name for item in itemlist" ng-model="chooseItem"></select>
           
//控制器中
$scope.chooseItem = "ccc";
$scope.itemlist = [
  {
    id: "aaa",
    name: "AngularJS"
  }, {
    id: "bbb",
    name: "我勒個擦"
  }, {
    id: "ccc",
    name: "呵呵"
  }
];
           

下拉框中分别是”AngularJS”、”我勒個擦”、”呵呵”,且将預設選中 呵呵

八、

directive

傳回對象用法

(1) link

.controller("DemoCtrl", function($scope){
  $scope.name = "呵呵哒";
})
.directive("directiveDemo", function () {
  return {
    //連結函數,三個參數分别為:作用域、元素(jQLite對象數組)、屬性集
    link: function (scope, element, attrs) {
      //呵呵哒
      console.log(scope.name);
      //2015
      console.log(element.eq().attr("renrenche"));
      //2015
      console.log(attrs["renrenche"]);
    }
  }
})
           
<!-- HTML -->
<body ng-controller="DemoCtrl">
  <directive-demo renrenche="2015"></directive-demo>
</body>
           

(2)template

return {
    //将指令内容表示為HTML
    template: "<div>2015</div>"
    //或函數形式,參數分别為元素、屬性集
    template: function(element, attr){
      return "<div>" + attr["renrenche"] + "</div>"
    }
}
           

效果:

<directive-demo renrenche="2015">
  <div>2015</div>
</directive-demo>
           

(3)replace

注意:屬性會轉移到模版内容中

return {
    //将指令内容表示為HTML
    template: "<div>2015</div>"
    //布爾值
    replace: true
}
           

值為true時,将指令替換為模版内容,預設為false。

效果:

(4)templateUrl

用外部模版進行替換,與template用法相似。隻是把模版内容換為url。

return {
    templateUrl: "tamplateDemo.html"
    //或函數形式,參數分别為元素、屬性集
    template: function(element, attr){
      return "tamplateDemo.html";
    }
}
           

(5)restrict

指定指令如何被使用

return {
    restrict: "EACM"
}
           

取值:

E: Element 元素

A: Attribute 屬性

也可以指派

參數通過

attr["directiveDemo"]

擷取

C: Class 類名(不常用)

也可以提供配置值,angular會當作屬性呈現該資訊

參數通過

attr["directiveDemo"]

擷取

M: Comment 注釋(不常用)

必須以directive單詞開始,跟随一個冒号、指令名以及可選參數。(實在感覺這種方式太難用,不作過多介紹)

預設為EA,也是最常用的兩種方式。

(6)scope

為指令建立一個新的作用域或者隔離的作用域

使用一:布爾值,建立一個新的作用域

return {
    scope: true
}
           

例:對于如下例子,任一input内容發生變化,另外一個都将跟随改變,因為他們共享一個作用域

.controller("DemoCtrl", function($scope){
  $scope.name = "呵呵哒";
})
.directive("directiveDemo", function () {
  return {
    template: "<input type='text' ng-model='name'>",
    replace: true,
  }
})
           
<!-- HTML -->
<div ng-controller="DemoCtrl">
  <directive-demo></directive-demo>
  <directive-demo></directive-demo>
</div>
           

如果想讓它們分别有自己的作用域,設定scope為true即可。

.directive("directiveDemo", function () {
  return {
    template: "<input type='text' ng-model='name'>",
    replace: true,
    scope: true
  }
})
           

但是如果通路的是挂載在一個對象上的屬性時,将保持同步,如:

.controller("DemoCtrl", function($scope){
  $scope.data = {
    name: "呵呵哒"
  }
})
.directive("directiveDemo", function () {
  return {
    template: "<input type='text' ng-model='data.name'>",
    replace: true,
    scope: true
  }
})
           

使用二:建立一個隔離的作用域

return {
    scope: {}
}
           

此時指令将不繼承所在的控制器的作用域。即對于上面的例子而言,此時将通路不到

name

data.name

等屬性。

繼續閱讀