1. 程式人生 > >前端開發框架總結之Angular實用技巧(六)

前端開發框架總結之Angular實用技巧(六)

                                    前端開發框架總結之Angular實用技巧(六)

上文講了Angular中依賴注入相關知識,掌握了這些,我們就可以在前端的邏輯更清晰明瞭,複用程度也更高。今天我們對Angular系列做一個收尾,把一些零零碎碎的小技巧總結下。

  • 程序間通訊

我們使用事件的方式進行程序間的通訊。主要用到如下幾個方法。$on,$emit,$broadcast.

$on,用來接收事件和引數。接收到得事件包括以下幾個主要的屬性,name(事件名稱)、targetScope(發出時間的scope)、currentScope(接收事件的scope)、stopPropagation方法(阻止emit時間繼續冒泡)

$emit, 用於向父scope傳送事件。(傳送事件所在的scope中也可以監聽到,這個在自定義元件中可能會用到)

$broadcast 用於向子scope傳送事件。(本身所在的scope也可以監聽的到)

js程式碼:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
  <title>angular程序間通訊</title>
</head>
<body ng-app="ExampleApp">

  <div ng-controller="parentCtrl">
      <button ng-click="clickParent()" >parent</button>

      <div ng-controller="child1Ctrl">

          <button ng-click="clickChild()" >child1</button>
          <div ng-controller="subChildCtrl">
              <button ng-click="clickSubChild()" >subChild</button>
          </div>

      </div>

      <div ng-controller="child2Ctrl">

      </div>
  </div>

  <script src="jquery-3.2.1.min.js"></script>
  <script src="angular.js"></script>

  <script>
      var app = angular.module('ExampleApp', []);

      app.controller('parentCtrl',['$scope', function ($scope) {
          console.log('enter parentCtrl');
          var obj = new Object();
          obj.data = 'from parent';

          var test = 'testContent';

          $scope.getObj = function () {
              return test;
          }

          $scope.clickParent = function () {
              $scope.$broadcast('parentEvent',obj);
          }

          $scope.$on('child1Event',function (event, args) {
          });

          $scope.$on('parentEvent',function (event, args) {
              debugger;
          });

      }]);

      app.controller('child1Ctrl',['$scope', function ($scope) {
          console.log('enter child1Ctrl');
          var obj = new Object();
          obj.data = 'from child1';

          $scope.clickChild = function () {
              $scope.$emit('child1Event',obj);
          }

          $scope.$on('parentEvent',function (event, args) {
              console.log('方法呼叫:' + $scope.getObj());
          });

          $scope.$on('child1Event',function (event, args) {
              debugger;
          });

          $scope.$on('subChildEvent',function (event, args) {
              debugger;

              event.stopPropagation();
          });


      }]);

      app.controller('child2Ctrl',['$scope', function ($scope) {
          console.log('enter child2Ctrl');

          $scope.$on('parentEvent',function (event, args) {
              debugger;
          });

          $scope.$on('child1Event',function (event, args) {
              debugger;
          });

      }]);

      app.controller('subChildCtrl',['$scope', function ($scope) {
          console.log('enter subChildCtrl');
          var obj = new Object();
          obj.data = 'from subChild';

          $scope.$on('parentEvent',function (event, args) {
              debugger;
          });

          $scope.$on('child1Event',function (event, args) {
              debugger;
          });

          $scope.clickSubChild = function () {
              $scope.$emit('subChildEvent',obj);
          }

      }]);


  </script>
</body>
</html>
  • $interval使用

interval的使用本身沒有什麼難度,但是要注意防止放生記憶體洩露,因為interval發起的定時任務,如果不清除的話,會一直迴圈執行。方法如下

          var timer = $interval(function () {
              console.log('enter interval ')
          },5000);


          $scope.on('$destory',function () {
              $interval.cancel(timer);
          });
  • ng-if,ng-show

​​​​​​​ng-if如果條件不滿足是不會生成對應元素的,ng-show只是不顯示對應元素而已。這個要根據實際情況使用的。

  • 巧用ng-class ng-style

​​​​​​​巧用ng-class,ng-style可以使我們儘可能少的直接操縱頁面元素來實現頁面的動態效果。

直接上例子

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
  <title>ng-class,ng-style巧用</title>

  <style>
    .myBtn{
      height: 36px;
      background-color: white;
      border: 1px solid #f5f5f5;

    }

    .myBtn.select{
      background-color: darkseagreen;
    }

  </style>
</head>
<body ng-app="ExampleApp">

  <div ng-controller="testCtrl">
    <div>

      <button ng-click="clickBtn($event)" ng-class="{'myBtn':true,'select':btn[0].select}" data-index="0">選中我</button>
      <button ng-click="clickBtn($event)" ng-class="{'myBtn':true,'select':btn[1].select}" data-index="1">選中我</button>
    </div>

    <div>
      <button ng-style="myStyle" ng-click="changeStyle()">改變style</button>
    </div>
  </div>

  <script src="jquery-3.2.1.min.js"></script>
  <script src="angular.js"></script>

  <script>
      var app = angular.module('ExampleApp', []);

      app.controller('testCtrl',['$scope', function ($scope) {
          console.log('enter testCtrl');

          $scope.btn = [
              {
                  'select':false
              },
              {
                  'select':false
              },
          ];

          $scope.clickBtn = function (event) {
              $scope.btn[event.target.dataset.index].select = !$scope.btn[event.target.dataset.index].select;
          }

          $scope.myStyle = {
              'background':'red'
          };

          $scope.changeStyle = function () {
              $scope.myStyle.background = 'yellow';
          }
      }]);



  </script>
</body>
</html>
  • 過濾器

​​​​​​​過濾器分為原生自定的過濾器和自定義過濾器兩種,過濾器可以用在表示式型別的繫結和ng-bind型別的繫結上,不能用在ng-model,如果想在ng-model實現類似功能可以使用自定義指令。

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
  <title>angular過濾器使用</title>

  <style>
    .ng-cloak{
      display: none;
    }
  </style>
</head>
<body ng-app="ExampleApp">

  <div ng-controller="testCtrl" >
    <div>
      <span class="ng-cloak">{{testContent | uppercase}}</span>
    </div>
    <div>
      <span ng-bind="testContent | reverse"></span>
    </div>

  </div>

  <script src="jquery-3.2.1.min.js"></script>
  <script src="angular.js"></script>

  <script>
      var app = angular.module('ExampleApp', []);

      app.controller('testCtrl',['$scope', function ($scope) {
          console.log('enter testCtrl');

          $scope.testContent = 'aaa bbb ccc';

      }]);

      app.filter('reverse', function() { //可以注入依賴
          return function (text) {
              return text.split("").reverse().join("");
          }
      });

  </script>
</body>
</html>

示例中的程式碼有一個防止載入頁面時{{}}閃爍的解決技巧。

  • 校驗

​​​​​​​校驗分為自定校驗和原生校驗兩種。直接上例子。

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
  <title>angular-test</title>
</head>
<body ng-app="ExampleApp">

<div ng-controller="MainCtrl">
  <form name="testForm">

    <input name="test" ng-model="name" validate-name>

    <div ng-show="testForm.test.$error.validRule">
      輸入內容不合法
    </div>
  </form>

</div>

<script src="jquery-3.2.1.min.js"></script>
<script src="angular.js"></script>


<script>
    var app = angular.module('ExampleApp', []);

    app.controller('MainCtrl', function ($scope,$timeout) {

        $scope.name= '';
    });

    var INTEGER_REGEXP = /^[\u4E00-\u9FA5a-zA-Z0-9_]{0,20}$/;

    app.directive('validateName',function () {
        return {
            restrict: 'A',
            require:'?^ngModel',
            link:function (scope,element,attrs,ngModel) {
                ngModel.$validators.validRule = function (modelValue,viewValue) {
                    if(INTEGER_REGEXP.test(viewValue)){
                        return true;
                    }

                    return false;
                }
            }
        }
    });
</script>
</body>
</html>
  • 使用$parsers和$formatters對內容進行轉化

​​​​​​​parsers是頁面內容到model值得轉化,formatter是從model到頁面值得轉化。直接上例子

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
  <title>angular ngModel的parser和formatter使用</title>
</head>
<body ng-app="ExampleApp">

  <div ng-controller="testCtrl" >
    <span>model的值:{{inputTest}}</span>
    <div>
      <input ng-model="inputTest" my-input>
    </div>
    <button ng-click="changeValue()">change</button>

  </div>

  <script src="jquery-3.2.1.min.js"></script>
  <script src="angular.js"></script>

  <script>
      var app = angular.module('ExampleApp', []);

      app.controller('testCtrl',['$scope', function ($scope) {
          console.log('enter testCtrl');

          $scope.inputTest = '';

          $scope.changeValue = function () {
              $scope.inputTest = "賦初值";
          }

      }]);

      app.directive('myInput',function () {
          return {
              restrict: 'A',
              require:'?^ngModel',
              link:function (scope,element,attrs,ngModel) {

                  //把輸入的值都預設的轉化為大寫。
                  ngModel.$parsers.push(function (value) {
                      value = value.toUpperCase();

                      return value;
                  });

                  ngModel.$formatters.push(function (value) {
                      if(value){
                          value = value + '轉化後的值';
                      }

                      return value;
                  });
              }
          }
      });


  </script>
</body>
</html>

angular系列就到此為止,希望對大家有所幫助。