蛙蛙推薦:AngularJS學習筆記


為了降低前端代碼的數量,提高可維護性,可測試性,學習了下AngularJS,正在准備投入項目開發中。

AngularJS的概念比較多,如果面向對象方面的書理解的不透的話學習起來有些費勁,它的官方有個快速入門不錯,中文版如下

http://www.ituring.com.cn/minibook/303

但除了入門外,要真實的寫項目還是得把模塊划分,依賴關系處理,組件間通信,文件目錄安排等問題解決好才能干活。

根據這個學習目的,寫了個DEMO,地址如下

http://onlytiancai.github.io/codesnip/angular-demo1.html

 

  1. 頁面初始化時有3個蘋果,3個桔子,用戶可以在輸入框里重新輸入桔子和蘋果的數量,界面會有相應的變化
  2. 定義了兩個模塊
    1. common是通用模塊,
      1. 包含一個commonErrorMsg的directive用來顯示全局的錯誤信息, 通過監聽common.showerror事件來獲取信息,並讓字體顯示為紅色
    2. myApp是整個單頁面應用的模塊,
      1. 包含inputCtrl, statusCtrl兩個controller
      2. 包含fruits, orange, apple三個directive
      3. 包含range的filter
      4. 包含fruitsService的service
  3. 總體依賴關系如下
    1. myApp依賴common
    2. fruits, inputCtrl, statusCtrl都依賴fruitsService
    3. inputCtrl通過事件隱含依賴common
    4. 總體來說上層module依賴底層module,上層controller依賴底層service
  4. fruits是一個自定義的directive,用來顯示所有水果
    1. transclude=True表示它的子元素也受它管理,比如里面的時蘋果和桔子
    2. 該directive要和inputCtrl進行通信,以便動態更改水果的數量, 所以它和inputCtrl共同依賴fruitsService,並通過fruitsService的事件進行通信。
  5. 事件基本是全局的,所以定義事件時盡量有個命名空間, 如common.showerror, fruitsService.updated
  6. orange和apple是兩個很普通的directive,其中apple還掩飾了directive里如何處理自身的UI事件
  7. statusCtrl就監聽fruitsService.updated事件,並更新自己的狀態
  8. inputCtrl里watch自身UI里的兩個ng-model,適時調用fruitsService的相關方法
    1. 如果界面輸入太大的數字,會向common.showerror發送消息,以在界面上提示給用戶 這里沒有用ng-form自帶的驗證就是為了演示模塊間如何通信
  9. range的filter是彌補ng-repeat的不足,讓它支持類似 x in range(10)的形式
  10. fruitsService純粹是為了directive之間或controller之間通信和共享數據所設計

HTML代碼

<!doctype html>
<html ng-app="myApp">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <script src="angular.js"></script>
        <script src="angular-demo1.js" charset="utf-8"></script>
        <title>AngularJS Demo</title>
    </head>
    <body>
        <p common:error_msg></p>
        <p ng-controller="statusCtrl">一共有{{apple_count}}個蘋果,{{orange_count}}個桔子。</p>
        <fruits>
            <apple ng-repeat="n in [] | range:apple_count"></apple>
            <orange ng-repeat="n in [] | range:orange_count"></orange>
        </fruits>
        <p ng-controller="inputCtrl">請輸入
        <input type="text" ng-model="apple_count" />個蘋果,
        <input type="text" ng-model="orange_count" />個桔子      
        </p>
    </body>
</html>

 

js代碼

angular.module('common', []);
angular.module('common').directive('commonErrorMsg', function(){
    return {
        restrict: "A",
        controller: function ($scope, $element, $attrs) {
            $element.css('color', 'red');
            $scope.$on('common.showerror', function (ev, msg) {
                $element.html(msg);
            });
        }
    }
});

var myApp = angular.module('myApp', ['common']);
myApp.directive('fruits', function(fruitsService) {
    return {
        restrict: "E",
        transclude: true,
        replace: true,
        template: '<ul ng-transclude></ul>',
        controller: function ($scope, $element, $attrs) {
            $scope.$on('fruitsService.updated', function () {
                $scope.apple_count = fruitsService.apple_count; 
                $scope.orange_count = fruitsService.orange_count;      
            });
        }
    }
})
.directive('orange', function() {
    return {
        restrict: "E",
        template: '<li>桔子</li>'
    }
})
.directive('apple', function() {
    return {
        restrict: "E",
        template: '<li><a ng-click="show()" href="#">蘋果</a></li>',
        link: function(scope, element, attrs) {
            scope.show = function(){
                alert('我是一個蘋果');
            }; 
        }
    }
})
.controller('statusCtrl', function($scope, fruitsService) {
    $scope.$on('fruitsService.updated', function () {
        $scope.apple_count = fruitsService.apple_count; 
        $scope.orange_count = fruitsService.orange_count;      
    });    
})
.controller('inputCtrl', function($scope, fruitsService, $rootScope) {
    $scope.$watch('apple_count', function (newVal, oldVal, $scope) {
        if (newVal > 10){
            $rootScope.$emit('common.showerror', '蘋果數量太多了');
        }else{
            fruitsService.set_apple_count(newVal);
        }
    }, true);
    $scope.$watch('orange_count', function (newVal, oldVal, $scope) {
        if (newVal > 10){
            $rootScope.$emit('common.showerror', '桔子數量太多了');
        }else{
            fruitsService.set_orange_count(newVal);
        }
    }, true);
    fruitsService.set_apple_count(3);
    fruitsService.set_orange_count(2);
})
.filter('range', function() {
    return function(input, total) {
        total = parseInt(total);
        for (var i=0; i<total; i++)
            input.push(i);
        return input;
    };
})
.service('fruitsService', function ($rootScope) {
    this.set_apple_count = function (apple_count) {
        this.apple_count = apple_count;
        $rootScope.$broadcast('fruitsService.updated');
    };
    this.set_orange_count = function (orange_count) {
        this.orange_count = orange_count;
        $rootScope.$broadcast('fruitsService.updated');
    };
});

下面這篇帖子也很好,關於如何用AngularJS開發大型項目的。

如何組織大型JavaScript應用中的代碼?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM