angular入门(1.x)

angular.js:

教程可以作为跳板,因为vue也参考了angular的设计。

angular.js是google开源的前端js结构化框架

第一次学习结构化框架,它和函数库有什么区别呢?

比如jQuery中,安装之后,可以在编写js中有一个$符帮助我们去寻找特定的方法,方便记忆和使用(能够提高效率),在jQuery中所有的都是属于函数调用(对内容封装,给出api)。

 angular.js的特性和优点:

双向数据绑定

声明式依赖注入

解除耦合应有逻辑,数据模型和视图。(耦合度,会让开发比较困难,在不知情的情况下,容易牵一发而动全身)

完善的页面指令

定制表单验证

Ajax封装

 

与jQuery比较:

jQuery让开发更加方便了;{js函数库,封装简化dom操作}

 

angular:js结构化框架,主体不再是dom而是页面中动态的数据;(它相当于在页面和内存中建立连接,关注数据的动态变化)

 

angular能做什么项目:构建单页面(SPA)web应用,web app应用;应用(饿了么,淘宝,知乎周报等);

 

单页面应用:

single page application'特点:

1.活动只局限在一个页面

2.当页面中有部分数据发生了变化不会刷新整个页面而是局部刷新

3.利用ajax技术,路由。

 

angular:语法1.x是javascript写的,新版使用typescript写的;(有依赖关系)

相当于属性一样的标记(监管动态数据,而不是dom操作)

ng-app告诉angular核心它管理当前标签所包含的整个区域,并且创建$rootScope根作用域对象

ng-model将当前输入框的值与谁相关联(属性名:属性值),并作为当前作用域对象($rootScope)的属性;

{{}}(表达式):显示数据,从作用域对象的指定属性名上取;

1.表达式:通常有一个返回值,可以放在任何需要值得地方,比如函数调用的参数,一个是变量名,一个运算

2.语句:通常表示一个完整的执行单位,一段完整的js代码,有的语句可以使用表达式来执行,叫做表达式语句

3.区别:语句用分号结尾,有些语句我们没有加分号,比如console.log()虽然没有加分号,但也是语句;js引擎会自动加分号

4.特例:if语句就不用加分号,可也是一个完整的语句;    

 

 

双向数据绑定:

1.数据绑定:

数据从一个地方A转移到另一个地方B,而且让这个操作由框架来完成

 

2.双向数据绑定:数据可以从视图view流向model也可以从model流向view

view:也就是当前页面;(主要是angular指令和表达式)

model:作用域对象($rootScope),它可以包含一些属性或方法

当改变view中的数据,model对象的对应属性,也会随之改变,ng-model指令数据从view流向model

当model域对象属性发生变化时,页面对应随之更新{{}}表达式,数据从model中流向view

 

3.ng-init初始化当前作用域变量;单向数据流动

 

作用域对象和控制器对象:

ng-controller:指定控制器构造函数,Angular会自动new此函数创建控制器对象

同时Angular还有创建一个新的作用域对象$scope,它是$rootScope的子对象。(只限于这个ng-controller作用域,但是在这种作用域中,可以向全局的作用域中获取对象。)

在控制器函数中声明$scope形参,Angular会自动将$scope传入

 

 

依赖对象:

完成某个特定的功能,需要某个对象才能实践,这个对象就是依赖对象。

 

依赖注入:依赖的对象以形参的 形式被注入进来使用,这种方式就是依赖注入(声明式)。

 

angular的$scope就是依赖对象,并且是依赖注入的形式进行使用,

!形参必须是特定的名称,否则Angular无法注入抛出异常。

 

回调函数的event的就是依赖对象

回调函数有形参就是依赖注入;

 

 

依赖注入:

声明式依赖注入:更加注重执行的结果

对命令结构进行局部包装

 

命令式依赖注入:更加注重执行的过程

没有包装需要一步一步的解答

 

模块对象和控制器对象(为什么要使用这个对象,就是为了能够改变轻松的改变页面):

 

可以通过创建模块对象

 

ng-app可以指定一个区域的名字;

创建方式;

 

ng-app="myApp"

 

var myModule=angular.module("myApp",[])

 

生成作用域对象:

ng-controler="MyController"

myModule.controller("MyController",function($scope){})

 

链式调用:

angular.module('myApp',[])

.controller('MyController',function($scope){

$scope.empName-'kobe';

})

.controller(MyController2",function($scope){

$scope.empName='kobe2';

})

 

链式调用说明每一个函数有返回值,这个返回值是模块对象;

由于angular在压缩的时候会将$scope压缩为任意字母所以传参的时候可以使用数组传递的方式,防止angular的$scope被压缩;

链式调用:

angular.module('myApp',[])

.controller('MyController',['$scope',function($scope){

$scope.empName-'kobe';

}])

 

这种方式叫做显示声明依赖;(第二个$scope可以写任何形参,angular.module没有依赖)

 

表达式:

表达式中的可以调用javascripe代码,如果不加''的字符被认为是变量

 

 

常用的指令:

ng-click点击事件:ng-click="回调函数"

 

ng-repeat:遍历数组显示元素;

有点像for in循环

 

<li ng-repeat="person in persons">

{{person.username}}--{{person.age}}

</li>

其中person是取自数组的一个单位

 

$index显示下标,遍历的时候的下标

 

$first

 

$last

 

$middle中间的为true(除了第一个和最后一个)

 

$odd奇数为true

 

$even偶数为true

 

返回一个boolean值

 

这个方法会产生多个作用域,数组有多少元素就有多少个作用域

 

ng-bind:解决表达式闪屏的问题。当网速加载文档比较慢的时候,就会出现写在html中的代码被解析出来,导致网页中展现太多的代码,(由于浏览器加载的时候是从上向下解析的所以,上面的angular标记会率先解析出来,从而影响用户体验,而且可能影响到浏览器的渲染)

 

ng-bind="这个标签中塞的内容"(这个方法的原理是,浏览器解析的时候不会先读取启动不认识的标签属性,而是等待文档加载之后才会将这个属性中的值,塞到标签中去)

 

ng-show

ng-hide里面放置boolean类型,如果是true则执行,否则不执行

 

ng-class:动态引用定义的样式

ng-class={属性名的类:boolean值}{$odd,$even返回值是boolean值,可以将这个放到上面}

 

ng-style:动态的引用通过js的样式对象内部的属性值要使用''

ng-style={

backgroud:"red";

}

 

ng-mouseenter="方法"

 

ng-mouseleave="方法"

 

1.localstorage永久存储

生命周期:永久保存只要浏览器还在,不被手动清除;

大小:5M甚至更大

setItem('key',value);

 

getItem('key');

 

removeItem('key');

 

2.sessionstorage会话存储

生命周期:页面打开到关闭

大小:5M

setItem('key',value);

 

getItem('key');

 

removeItem('key');

3.cookie

作用:用于保存浏览器和服务器端进行通信

特点:

大小:4kb

每次发送请求都携带,导致占用带宽

保存在浏览器端

cookie容易被截获(现在就有一些浏览的时候,之后会被推送广告就是因为cookie被截获了)

cookie的生命周期:

会话cookie:浏览器打开到关闭;

人为设置cookie:人为设置时间;

 

练习1:剩余字数功能实现;

<!DOCTYPE html>

<html>

    <head>

        <meta charset="utf-8">

        <title>剩余字数功能的实现</title>

        <style type="text/css">

            textarea{

                resize: none;

            }

        </style>

    </head>

    <body ng-app='myApp'>

        <div ng-controller='myController'>

            <h2>我的笔记</h2>

            <textarea rows="10" cols="30" ng-model='message'>

                

            </textarea>

            <div id="">

                <button type="button"  ng-click='save()'>保存</button>

                <button type="button" ng-click='read()'>读取</button>

                <button type="button" ng-click='delete()'>删除</button>

            </div>

            <p>剩余的字数:{{getCount()}}</p>

        </div>

        

        <script src="../../source/angular-1.5.5/angular.js" type="text/javascript" charset="utf-8"></script>

        <script type="text/javascript">

            angular.module('myApp',[]).controller('myController',['$scope',function($scope){

                //为什么要在这里给它定义一个字符串,原因是在文档读取的时候没有给message赋值和定义类型,如果刚开始就直接调用{{getCount()}},就会报错,而100-undefined.length就更错了

                $scope.message='';

                

                $scope.getCount=function(){

                    var x=$scope.message.length;

                    if(x<=100){

                        return 100-$scope.message.length;

                    }

                    else{

                        // 使用slice截取0到100的子串的内容将它覆盖

                        $scope.message=$scope.message.slice(0,100);

                        return 0;

                    }

                }

                $scope.save=function(){

                    // 保存的时候最好将内容转换成JSON字符串这样安全一点,读的时候在转换回来

                    if($scope.message){

                    localStorage.setItem("message",JSON.stringify($scope.message));

                    console.log('保存成功');

                    }else{

                        console.log('无内容');

                    }

                }

                $scope.read=function(){

                    var read1=localStorage.getItem("message");

                    // console.log(read1);

                    if(read1){

                    console.log('读取成功成功');

                    // 只有read1中有值时才能被转化,否则会报错,返回空串不行。

                    $scope.message=JSON.parse(read1);

                    }else{

                        console.log("无内容");

                    }

                }

                

                $scope.delete=function(){

                    if($scope.message){

                        console.log('删除成功');

                        $scope.message='';

                    }

                    else{

                        if(!localStorage.getItem("message")){

                            console.log("无内存数据");

                        }

                        else if(confirm("是否删除内存?")){

                            localStorage.removeItem("message");

                            console.log('删除内存成功');}

                    }

                }

            }])

        </script>

    </body>

</html>

 

练习2:数据动态显示

 

<!DOCTYPE html>

<html>

    <head>

        <meta charset="utf-8">

        <title>数据的动态显示</title>

        

    </head>

    <body ng-app="myApp">

        <div ng-controller="myController">

            <h2>我的备忘录</h2>

            <div>

                <input type="text" ng-model='newTodo'/>

                <button type="button" ng-click='add()'>添加</button>

            </div>

            <div ng-repeat="todo in todos">

                <!-- ng-model是双向的,所以在选中时就会变成true -->

                <input type="checkbox" ng-model='todo.isChecked'/>

                <span>{{todo.name}}</span>

            </div>

            <button type="button" ng-click="delete()">删除所选的记录</button>

        </div>

        <script src="../../source/angular-1.5.5/angular.js" type="text/javascript" charset="utf-8"></script>

        <script type="text/javascript">

            angular.module('myApp',[])

            .controller('myController',["$scope",function($scope){

                $scope.newTodo='';

                $scope.todos=[

                    {name:'吃饭',isChecked:false},

                    {name:'逛街',isChecked:true},

                    {name:'拉屎',isChecked:false}

                ]

                $scope.add=function(){

                    if($scope.newTodo){

                        // $scope.todos.push($scope.newTodo);这样不行啊,因为添加的是一个对象,而这里面是一个字符串,所以要对信息进行收集整理;

                        var oTodo={name:$scope.newTodo,isChecked:false};

                        // $scope.todos.push(oTodo);末尾添加最后数据多不好看,最好放在最前面

                        $scope.todos.unshift(oTodo);

                        console.log($scope.todos)

                    }

                    else{

                        alert("请输入具体的行为!嘤嘤嘤~~");

                    }

                }

                $scope.delete=function(){

                    if(!confirm("是否拜拜日常行为?点击是就再也见不到了哦")){return;}

                    // $scope.todos.forEach(function(item,index){

                    //     // 这样的方法只能删除一个数据,而forEach中不能使用循环判定固定数据

                        

                    //     if(item.isChecked){

                    //         $scope.todos.splice(index,1);

                    //         // 采用递归调用直至删除完毕,采用递归必须有结束条件不然循环多次啊

                    //         // $scope.delete();这个方式就失去提示的机会了

                    //         $scope.delete();

                    //     }

                        

                    // })

                    // 创建新的引用

                    var otodos=$scope.todos;

                    // 重新引入数组将新的数组放到对应位置

                    $scope.todos=[];

                    otodos.forEach(function(item,index){

                        if(!item.isChecked){

                            // 注意插入的顺序

                            $scope.todos.push(item);

                        }

                    })

                }

            }])

        </script>

    </body>

</html>

 

 

 

 

上一篇:开始 nx


下一篇:ng -----监听变化($scope.$watch())