Cordova webapp实战开发(五)- AngularJS基础篇(上)

随说:
笔者只是将 《AngularJS权威教程》这本书读了一遍,并且将里面能列举的内容用自己的话理解了一遍然后整理出来,编写顺序是按书本顺序作整理

1、 AngularJS数据绑定#

  1. 引入angular.js
  2. 在某个DOM元素上,明确设置ng-app属性(只有被ng-app属性的DOM元素区域才会受AngularJS影响)
  3. ng-model属性是AngularJS的一个指令,将内部数据模型对象的name绑定到文本输入字段上
  4. 数据绑定的格式{{ name }}
<!DOCTYPE html>
// 设置ng-app属性
<html ng-app>
    <head>
        <title>Simple app</title>
        // 引入JS
        <script
            src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.js">
            </script>
    </head>
    <body>
         // 可以这样理解,设置该DOM元素value值的KEY为name,然后可以通过{{ key }} , 获取该value
        <input ng-model="name" type="text" placeholder="Your name">
            // 绑定数据
            <h1>Hello {{ name }}</h1>
            </body>
</html>

再看一个例子

<!doctype html>
<html ng-app>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.js"></script>
    </head>
    <body>
        // DOM元素上 ng-controller 声明所有被它包含的元素都属于某个控制器。
        <div ng-controller="MyController">
        // 这里的{{clock}} 就是相当于这个值 $scope.clock , 也就是Date()函数的范围值
        <h1>Hello {{ clock }}!</h1>
        </div>
        <script type="text/javascript">
            // MyController 函数接收了两个参数, $scope , $timeout 
            function MyController($scope, $timeout) {
                var updateClock = function() {
                    $scope.clock = new Date();
                    $timeout(function() {
                             updateClock();
                             }, 1000);
                };
                updateClock();
            };
        </script>
    </body>
</html>

2、AngularJS模块#

AngularJS模块是定义应用的最主要方式,模块包含了主要的应用代码,一个应用可以包含多个模块,每一个模块都包含了定义具体功能的代码
模块定义代码 :

    //  第一个参数 : 模块名称
    //  第二个参数 : 依赖列表
    angular.module('name', []);

3、AngularJS作用域 - $scope#

AngularJS之$Scope

4、AngularJS控制器#

AngularJS的控制器是一个函数,用来向视图的作用域$scope中添加额外的功能。我们用它来给作用域对象设置初始状态,并添加自定义行为。

新建一个js文件。(一般以业务命名)
例如下面 app.js
在app.js下写上以下代码

// 定义一个名字为app的 模块。
var app = angular.module('app', []);
// 创建一个新的控制器,AngularJS会生成并传递一个新的$scope给这个控制器,
app.controller('FirstController', function($scope) {
 // 定义一个成员message并初始化值为“hello”
$scope.message = "hello";
});

AngularJS允许在$scope上升至包括对象在内的任何类型的数据,并且在视图中还可以展示对象的属性。
例如 :

var app = angular.module('myApp', []);
// 创建一个名字叫MyController的控制器
app.controller('MyController', function($scope) {
// 在MyController上创建一个person对象,并为这个对象创建一个名字为name 的属性,初始化值为Ari Lerner
$scope.person = {
name: 'Ari Lerner'
};
});


<div ng-app="myApp">
    // 在拥有ng-controller="MyController"的DOM元素内,或者任何子缘故中,都可以访问person对象,因为它是定义在$scope上的。
    <div ng-controller="MyController">
        <h1>{{ person }}</h1>
        and their name: <h2>{{ person.name }}</h2>
    </div>
</div>

控制器之间还可以嵌套,请看以下例子###

先创建两个控制器

app.controller('ParentController', function($scope) {
     $scope.person = {greeted: false};
});
 app.controller('ChildController', function($scope) { $scope.sayHello = function() {
     $scope.person.name = 'Ari Lerner'; };
});

下面是实现,将ChildController嵌套于ParentController内部,那childController的$scope对象的父级作用域就是ParentController的$scope对象。
我们可以在子作用域中,访问ParentController父作用域的内容。

<div ng-controller="ParentController">
    <div ng-controller="ChildController">
        <a ng-click="sayHello()">Say hello</a>
    </div>
    {{ person }}
</div>

在ChildController并没有定义person对象,可是却可以访问出对象,这就是控制器的嵌套关系,当子作用域中不存在对象时,会自动往上找,根作用域是rootScope

关于嵌套作用域之间,对象中的值的关系

// HTML代码
<div ng-controller="SomeController">
        {{ someBareValue }}
        <button ng-click="someAction()">Communicate to child</button>
        <div ng-controller="ChildController">
        {{ someBareValue }}
        <button ng-click="childAction()">Communicate to parent</button>
        </div>
</div>

// JavaScript代码
angular.module('myApp', [])
    .controller('SomeController', function($scope) {
          $scope.someBareValue = 'hello computer';
          $scope.someAction = function() {
          $scope.someBareValue = 'hello human, from parent';
    };
})
    .controller('ChildController', function($scope) {
          $scope.childAction = function() {
          $scope.someBareValue = 'hello human, from child';
    }; 
});

例子分析。

点击AAAA ,执行someAction() 函数,someBareValue的值这个时候是属于SomeController这个作用域下的,修改为'hello human, from parent',下面是点击AAAA后的执行结果

可以看到,在ChildController作用域下的someBareValue也改变了。由于继承关系,在ChildController作用域下的someBareValue实际上是通过父级对象从而获取出来的。
那这个时候,如果点击BBBBB,则会执行childAction()函数,也会修改someBareValue的值。效果如下


ChildController作用域下的someBareValue改变了,可是父级对象中someBareValue并没有改变,这说明

子控制器是复制而非引用someBareValue的值的,JavaScript对象要么是值复制,要么是引用复制。字符窜、数字、和布尔型变量是值复制,数组、对象、和函数则是引用复制####

5、AngularJS表达式#

例如前面用到的 {{}} 也是一个表达式
用 {{}} 符号将一个变量绑定到$scope上的写法本质上就是一个表达式 :{{ expression }}

AngularJS在执行$digest脏循环的过程中,会自动解释表达式,那如何手动解析表达式?

$parse服务####

在控制器中注入$parse服务(就是在创建contriller的时候,将$parse作为参数传入去。)

angular.module("myApp", [])

.controller('MyController', function($scope,$parse) {
    // $watch的使用,就是,监测ng-model="expr",的输入,并且将新值,旧值,作用域返回
    $scope.$watch('expr', function(newVal, oldVal, scope) {
if (newVal !== oldVal) {
   // 注入$parse后就可以使用,用$parse设置parseFun,就等于利用了$parse服务解释了得到的新值。
    var parseFun = $parse(newVal);
   // 定义parsedValue,并且调用parseFun,以此实现手动解析表达式
    $scope.parsedValue = parseFun(scope);
}
});
});

HTML代码

<div ng-controller="MyController"> <input ng-model="expr"
type="text"
 placeholder="Enter an expression" /> 
<h2>{{ parseValue }}</h2>
</div>

$interpolate服务

字符窜模板中做插值操作,利用了AngularJS 插值字符窜

<div ng-app="MyApp">
    <div ng-controller="MyController">
        <input ng-model="myName" type="text" placeholder="Type Your Name">
            <textarea ng-model="myTextarea" cols="30" rows="10"></textarea>
            <div ng-bind="interpolatedValue"></div>
            </div>
</div>
angular.module("MyApp", [])
// 在控制器中,我们设置了$watch来监视邮件正文的变化,并将myTextarea属性的值,进行字符插值后的结果赋值给myName属性
.controller("MyController", function($scope, $interpolate){
$scope.$watch("myTextarea", function(newVal, oldVal, scope){
var interpolatedFunc = $interpolate(' templeat : ' + newVal);
// 将input绑定的值,传入myName中
// interpolatedValue就是经过插值后的新值。
$scope.interpolatedValue = interpolatedFunc({myName: $scope.myName});
});

});

标识替换

假如你不想用 {{ }} 标识开始与结束,你可以通过$inter polateProvider 进行配置
startSymbol() 方法修改标识开始的符号
endSymbo() 方法修改标识结束的符号

angular.module('emailParser', [])
.config(['$interpolateProvider', function($interpolateProvider) {
$interpolateProvider.startSymbol('__');
$interpolateProvider.endSymbol('__');
}])

6、AngularJS过滤器#

过滤器就是用来过滤数据,使数据以你希望的形式展示出来,AngularJS有许多实用的内置过滤器。

使用过滤器有两种形式,HTML中调用过滤器,与JavaScript中调用过滤器

在HTML中的模板绑定符号{{}}内通过 | 符号来调用过滤器
例如 :

{{ name | uppercase }}

在JavaScript代码中可以通过$filter 来调用过滤器。
例如 :

app.controller('DemoController', ['$scope', '$filter',
function($scope, $filter) {
      $scope.name = $filter('uppercase')('Ari');
}]);

注意,可以用 | 符号作为分隔符来同时使用多个过滤器####

更多过滤器使用用法请参考这里

7、AngularJS指令#

创建自定义元素的函数称作指令,用.directive()方法创建,

.directive() 指令的使用。

例如,我们自己定义一个标签 <myDir></myDir>

<div>
      <my-dir></my-dir>
</div>
angular.module('myApp', [])

.directive('myDir', function() {
       return { restrict: 'E',
       replace: true,
       template: '<a href="http://google.com">简单来说,你在上面看到的<my-dir>表情已经没了</a>' };
});

结果,<my-dir></my-dir>被替换掉

<html ng-app>
    <head>
        <title>Simple app</title>
        <script
            src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.js">
            </script>
    </head>
    <body>
        <div>
              <a href="http://google.com">简单来说,你在上面看到的<my-dir>表情已经没了</a>
        </div>
    </body>
</html>

放一个自己的整理的例子

angular.module('myApp', [])
        
        .directive('myDirective', function() {
                   
          return {
                   //字符窜, 可选,在DOM中以何种形式被声明,E(元素),A(属性) , C (类名), M(注释)可单独或者混合使用
                   restrict: String,
                   // 
                   priority: Number,
                   // 布尔型参数,告诉AngularJS停止运行当前元素上比本指令优先级低的指令。
                   terminal: Boolean,
                   // 字符串或函数,可选,模板替换。
                   template: String or Template Function:
                   // 字符窜货函数,可选,一个可以接受两个参数的函数,并返回一个外部HTML文件路径的字符窜
                   function(tElement, tAttrs) (...},
                           //   模板的URL                  
                           templateUrl: String,
                          // 布尔型,可选 ,默认为false , 如果设置必须为true,
                          // false代表模板会被当作子元素插入到调用此指令的元素内部                     
                           replace: Boolean or String,
                           //  布尔型或对象,可选,默认为false
                           //  为true时,会自动从父作用域中继承并创建一个新的作用域
                           //   
                            scope: Boolean or Object,
                            transclude: Boolean,
                            controller: String or
                            function(scope, element, attrs, transclude, otherInjectables) { ... }, controllerAs: String,
                           require: String,
                           link: function(scope, iElement, iAttrs) { ... },
                           compile: //
                                               
                           function(tElement, tAttrs, transclude) {
                                               
                           return {
                                               
                            pre: function(scope, iElement, iAttrs, controller) { ... },
                            post: function(scope, iElement, iAttrs, controller) { ... }
                            }
                            // 或者
                            return function postLink(...) { ... }
                }
       };
});

指令是AngularJS中用的最多,最常用的功能,更多详细请看这里

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

推荐阅读更多精彩内容