蛙蛙推薦:AngularJS學習筆記

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

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

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

但除了入門外,要真實的寫項目仍是得把模塊劃分,依賴關係處理,組件間通訊,文件目錄安排等問題解決好才能幹活。前端

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

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

 

  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代碼angularjs

<!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代碼github

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開發大型項目的。app

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

學習

相關文章
相關標籤/搜索