一个例子 - 入门AngularJS

一. 为什么要使用AngularJS

Angular.js 是一个MVW(Model-View-Whatever,不管是MVC或者MVVM,统归MDV(model Drive View))JavaScript框架,个人更觉得像MVVM框架, 其是Google推出的专门用于SPA(single-page-application)应用框架.

  • 思考: MVVM模式是Model-View-ViewMode(模型-视图-视图模型)模式的简称,其最早出现在微软的WPF和Silverlight框架中, 现在AngularJS也是这一模式的继承者, 那么为什么这些框架都不遗余力的去实现这一模式, 这一模式有什么好处, 下面我们就从大家熟悉的silverlight开始, 剖析MVVM模式的实现, 以及为什么要使用AngularJS.

Silverlight中的MVVM(Model-ViewModel-View), 基于数据绑定的设计模式


  1. Model层: 一个简单学生实体模型
public class Student
{
    public string Name { get; set; }
    public int Age { get; set; }
    public DateTime Date { get; set; }
}
  1. ViewModel层: 通过继承INotifyPropertyChanged实现数据更新自动通知变化的数据绑定
public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
public class ViewModel : ViewModelBase
{
    public ViewModel()
    {
         Student = new Student();
         Student.Date = DateTime.Today.Date;
         Student.Name = "Jason";
         Student.Age = 18;
    }
    private Student _student;
    public Student Student
    {
        get
        {
            return _student;
        }
        set
        {
            _student = value;
            NotifyPropertyChanged("Student");
        }
    }
}
  1. View层(伪代码): 通过Binding写法绑定ViewModel中的数据, 同时可以配置绑定方式
<TextBox Text="{Binding Student.Name, Mode=OneWay}"/>
<TextBox Text="{Binding Student.Age, Mode=TwoWay}"/>
<TextBox Text="{Binding Student.Date, Mode=OneTime}"/>
  1. 参考: A Simple Silverlight Application Implementing MVVM

AngularJs中的MVW(Model-View-Whatever),个人理解为MVVM


  1. 示例代码
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<!----------------------引入AngularJs的包------------------------->
<script src="http://cdn.static.runoob.com/libs/angular.js/1.4.6/angular.min.js"></script>
<body ng-app="myApp" >
    <!------------------------View层------------------------------>
    <div ng-controller="myCtrl">
        姓名:  <input type="text" ng-model="student.name"><br>
        年龄:  <input type="text" ng-model="student.age"><br>
        入学时间:  <input type="text" ng-model="student.date"><br>
        
        <br>
        学生信息: {{student.name + " " + student.age +" " + student.date}}
    </div>
    <!------------------------View层------------------------------>
    
    <!-------ViewModel层($scope) / Controller层(controller)------->
    <script>
        var app = angular.module('myApp', []);
        app.controller('myCtrl', function ($scope) {
            //---------------Model层: student--------------//
            $scope.student = {
                name: "Jason",
                age: 17,
                date: "2015-04-01"
            };
            //---------------Model层: student--------------//
        });
    </script>
    <!-------ViewModel层($scope) / Controller层(controller)------->
</body>
</html>
  1. talk is cheap, show me the demo, try it yourself

  2. MVVM模式图

    image
  • 使用AngularJS的原因:

    1. 数据绑定: 一个完整的基于数据绑定的MVVM模式的框架,优势如下

      1. 低耦合:View可以独立于Model变化和修改,同一个ViewModel可以被多个View复用;并且可以做到View和Model的变化互不影响;
      2. 可重用性:可以把一些视图的逻辑放在ViewModel,让多个View复用;
      3. 独立开发:开发人员可以专注与业务逻辑和数据的开发(ViewModel),界面设计人员可以专注于UI(View)的设计;
      4. 可测试性:清晰的View分层,使得针对表现层业务逻辑的测试更容易,更简单。
    2. 可扩展HTML: 使用AngularJS,你可以操作XML一样操作HTML,创建自己的HTML标签和属性的定义, 在angualrjs中用==指令==(directive)来实现这一切, 如上面的ng-app, ng-controller都是angularjs自带的指令

    3. 依赖注入: 一种软件设计模式,在这种模式下,一个或更多的依赖(或服务)被注入(或者通过引用传递)到一个独立的对象(或客户端)中,然后成为了该客户端状态的一部分。在AngularJs中==服务==(Service)就通过依赖注入使用, 简单来说就是: ==没事你(服务)不要来找我,有事我会去找你(服务)。==

      // 定义一个模块
      var app = angular.module("myApp", []);
      
      // 创建服务 "AgeService" 
      app.service('AgeService', function() {
        // 用于判断年龄是否是成年人
         this.judgeAdult = function(age) {
            if (age >= 18) {
                 return true;
            } else {
                 return false;
            }
         }
      }); 
      
      // 在控制器中依赖注入AgeService服务
      app.controller('myCtrl', function ($scope, AgeService) {
          //---------------Model层: student--------------//
          $scope.student = {
              name: "Jason",
              age: 17,
              date: "2015-04-01"
          };
          //---------------Model层: student--------------//
          
          // 使用AgeService服务里面的方法判断是否成年
          $scope.isAdult = AgeService.judgeAdult($scope.student.age);
      });
      
      // 增加View层显示
      是否成年:  <input type="text" ng-model="isAdult"><br>
      
      

二. 如何开始学习AngularJS

  1. 从示例中了解AngularJS的基本概念
    1. 引用AngularJS包

      <script src="http://cdn.static.runoob.com/libs/angular.js/1.4.6/angular.min.js"></script>
      
    2. 启动AngularJS(ng-app):首先要告诉AngularJS我们的应用运行在DOM结构的哪一部分,我们可以把==指令ng-app==设在任何DOM元素上,然后该元素就会成为AngularJS启动运行我们应用的地方, 示例中 <body ng-app="myApp"></body> 告诉AngularJS拥有<body>下面的DOM区域并且从这里开始启动, 注意有且只能有一个地方标注ng-app.

      <body ng-app="myApp">
          // ... ...
      </body>
      
    3. 创建模块(Module): 注意到在上面ng-app="myApp"中myApp, 其实在AngularJS启动的时候有个启动器, 如果ng-app不带属性值,启动器就会自动初始化(默认配置)应用程序, 但是有属性值, 比如我们的myApp, 这代表告诉AngularJS要加载叫做myApp的模块作为初始化程序,所谓AngularJS模块,其实就是==一系列函数的集合==,当应用被启动时,这些函数就会被执行, 示例中创建了叫做“myApp”的AngularJS模块, 注意里面有个空的数组,这个数组是myApp模块依赖的模块的列表,为空代表会创建一个模块.

      // 创建myApp区域的模块
      var app = angular.module("myApp", []);
      
    4. 控制器(Controller): 控制 AngularJS模块的数据, 示例中为myApp模块增加了一个叫做myCtrl的控制器, 通过ng-controller="myCtrl" 在DOM中创建控制器并划定了控制的范围, ==同时创建了这个范围的作用域scope对象==, 在js控制器中可以传入并且访问scope对象, 例子中在$scope中创建了student对象, 我们就可以在ng-controller="myCtrl"属性的DOM元素==任何子元素==里访问这个student对象,实现双向绑定.

      // HTML
      <div ng-controller="myCtrl">
         //... ...
      </div>
      
      // JS
      app.controller('myCtrl', function ($scope) {
          $scope.student = {
              name: "Jason",
              age: 17,
              date: "2015-04-01"
          };
      });
      
    5. **作用域(scope)**: 是一个对象,有可用的方法和属性, 是应用在 HTML (视图) 和 JavaScript (控制器)之间的纽带, 示例中,在myCtrl的控制器中传入了scope对象, 在$scope中添加任何方法和属性, 在HTML(视图)指定的控制器下的DOM元素都可以访问这些属性方法.

      1. 作用域范围: 所有的应用都有一个 rootScope,它可以作用在 ng-app 指令包含的所有 HTML 元素中。rootScope 可作用于整个应用中。是各个 controller 中 scope 的桥梁。用 rootscope 定义的值,可以在各个 controller 中使用。
        <body ng-app="myApp">
            <div ng-controller="ParentController">
                <div ng-controller="ChildController">
                </div>
            </div>
        </body>
        
    6. 指令(Directive)和表达式: 上面的示例中不断出现各种原生HTML中没有的各种属性, 其实他们在AngularJS中叫做指令, AngularJS为我们创建了很多指令, ==指令实际上就是绑定在DOM元素上的函数==, 可以调用方法(ng-click), 定义行为(ng-app), 绑定控制器(ng-controller), 绑定数据(ng-model)等等.

      ng-app: 指令定义了AngularJS应用程序的根元素
      ng-model: 指令绑定HTML元素到应用程序数据。
      ng-controller: 指令定义了应用程序控制器。
      ... ...
      
      {{student.name}} : 表达式与 ng-model="student.name" 相同, 实现数据绑定
      
      1. 指令执行: 当一个AngularJS应用启动,Angular编译器就会遍历DOM树(从有ng-app指令属性的那个DOM元素开始),解析HTML,寻找这些指令函数。当在一个DOM元素上找到一个或多个这样的指令函数,它们就会被收集起来、排序,然后按照优先级顺序被执行
    7. 服务(Service): Services都是单例的,就是说在一个应用中,每一个Service对象只会被实例化一次(用$injector服务),主要负责==提供一个接口把特定函数需要的方法放在一起==, 就拿上面讲依赖注入的AgeService服务举例子, 这个服务就提供了判断是否成年的函数方法, 在需要的时候注入就可以直接使用, 非常方便. 同样, AngularJS内建了很多服务, 实现了很多功能, 以后在开发的时候直接注入进来就可以用了

      app.service('AgeService', function() {
        // 用于判断年龄是否是成年人
         this.judgeAdult = function(age) {
            if (age >= 18) {
                 return true;
            } else {
                 return false;
            }
         }
      }); 
      
  2. 详细的AngularJS使用教程: AngularJS教程 | 菜鸟教程
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,978评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,954评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,623评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,324评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,390评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,741评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,892评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,655评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,104评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,569评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,254评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,834评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,725评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,950评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,260评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,446评论 2 348

推荐阅读更多精彩内容