惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
C
Cisco Blogs
Scott Helme
Scott Helme
Know Your Adversary
Know Your Adversary
NISL@THU
NISL@THU
C
Cyber Attacks, Cyber Crime and Cyber Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
S
Schneier on Security
I
Intezer
Spread Privacy
Spread Privacy
AWS News Blog
AWS News Blog
V
Vulnerabilities – Threatpost
Cloudbric
Cloudbric
V2EX - 技术
V2EX - 技术
Google Online Security Blog
Google Online Security Blog
L
Lohrmann on Cybersecurity
Recent Commits to openclaw:main
Recent Commits to openclaw:main
L
LINUX DO - 热门话题
S
Secure Thoughts
T
The Exploit Database - CXSecurity.com
博客园 - 【当耐特】
Recent Announcements
Recent Announcements
Security Archives - TechRepublic
Security Archives - TechRepublic
Stack Overflow Blog
Stack Overflow Blog
罗磊的独立博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
K
Kaspersky official blog
阮一峰的网络日志
阮一峰的网络日志
博客园_首页
Latest news
Latest news
B
Blog
F
Full Disclosure
大猫的无限游戏
大猫的无限游戏
博客园 - 叶小钗
L
LangChain Blog
GbyAI
GbyAI
Last Week in AI
Last Week in AI
S
Security Affairs
Apple Machine Learning Research
Apple Machine Learning Research
N
Netflix TechBlog - Medium
Security Latest
Security Latest
Vercel News
Vercel News
Y
Y Combinator Blog
G
GRAHAM CLULEY
S
Securelist
T
Troy Hunt's Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
雷峰网
雷峰网

博客园 - 蛙蛙王子

蛙蛙推荐: TensorFlow Hello World 之平面拟合 [蛙蛙推荐]SICP第一章学习笔记-编程入门 快速学习C语言四: 造轮子,ArrayList 快速学习C语言三: 开发环境, VIM配置, TCP基础,Linux开发基础,Socket开发基础 快速学习C语言二: 编译自动化, 静态分析, 单元测试,coredump调试,性能剖析 快速学习C语言一: Hello World 转:python获取linux系统及性能信息 转帖:Python应用性能分析指南 蛙蛙推荐:快速自定义Boostrap样式 蛙蛙推荐:WEB安全入门 蛙蛙推荐:五分钟搞定网站前端性能优化 蛙蛙推荐:如何实时监控MySql状态 蛙蛙推荐:Backbone和seajs搭配最佳实践探讨 蛙蛙推荐:让SecureCRT好使起来 蛙蛙推荐:笨办法提高代码质量 蛙蛙推荐:一个程序员2012年技术学习总结 时髦的互联网公司都在用什么技术? 蛙蛙推荐:如何编写高质量的python程序 蛙蛙推荐:第一堂编程课提纲
蛙蛙推荐:AngularJS学习笔记
蛙蛙王子 · 2013-08-07 · via 博客园 - 蛙蛙王子

为了降低前端代码的数量,提高可维护性,可测试性,学习了下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开发大型项目的。