【总结】angularjs

一、介绍

AngularJS是一款由Google公司开发维护的前端MVVM框架,其克服了HTML在构建应用上的诸多不足,从而降低了开发成本提升了开发效率。

jQuery只是一个类库(类库指的是一系列函数的集合)以DOM做为驱动(核心),而AngularJS则一个框架(诸多类库的集合)以数据逻辑做为驱动(核心)。

MVC是一种开发模式,由模型(Model)、视图(View)、控制器(Controller)3部分构成,采用这种开发模式为合理组织代码提供了方便、降低了代码间的耦合度、功能结构清晰可见。

模型(Model)一般用来处理数据(读取/设置),一般指操作数据库。

视图(View)一般用来展示数据,比如通过HTML展示。

控制器(Controller)一般用做连接模型和视图的桥梁。

Angular使用MVVM框架

 

 它采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然

  • M - Model 数据:它是与应用程序的业务逻辑相关的数据的封装载体
  • V - View 视图:它专注于界面的显示和渲染
  • VM - ViewModel 视图-数据:它是View和Model的粘合体,负责View和Model的交互和协作

二、模块化(Module)

1、定义应用(view)

通过为任一HTML标签添加ng-app属性,可以指定一个应用,表示此标签所包裹的内容都属于应用(App)的一部分。

2、定义模块(model)

AngularJS提供了一个全局对象angular,在此全局对象下存在若干的方法,其中angular.module()方法用来定义一个模块。

angular.module(‘模块名’,[依赖的其它模块])

没有依赖也要写【】否则会报错

注:应用(App)其本质也是一个模块(一个比较大的模块)。

3、定义控制器

控制器(Controller)作为连接模型(Model)和视图(View)的桥梁存在,所以当我们定义好了控制器以后也就定义好了模型和视图。

       app.controller(“控制器名”,[依赖的服务,function(依赖的服务){

])

模型(Model)数据是要展示到视图(View)上的,所以需要将控制器(Controller)关联到视图(View)上,通过为HTML标签添加ng-controller属性并赋值相应的控制器(Controller)的名称,就确立了关联关系。

三、指令

1、内置指令ng开头

1)ng-app 指定应用根元素,至少有一个元素指定了此属性。

不能写在<head>上

2)ng-controller指定控制器。

3)ng-repeat=“(key,value) in 循环的数组”

4ng-switch onng-switch-when可以对数据进行筛选

<ling-repeat="item in items" ng-switch on="item">

            <spanng-switch-when="css">{{item}}</span>

</li>

当item=“css”时,才显示span

ng-switch on中的是判断的变量,相当于swich(中的变量);

ng-swich-when中是条件,相当于case

5)ng-bind显示模型的数据(和{{}}一样)

   ng-bing-template可以绑定多个数据

 ng-clock属性选择器,相当于后面有个display:none,所以用户看不到{{}}

ng-cloak 指令用于在 AngularJS 应用在加载时防止 AngularJS 代码未加载完而出现的问题。

AngularJS 应用在加载时,文档可能会由于AngularJS 代码未加载完而出现显示 AngularJS 代码,进而会有闪烁的效果, ng-cloak 指令是为了防止该问题的发生。

6)ng-show控制元素是否显示,true显示、false不显示

7)ng-hide控制元素是否隐藏,true隐藏、false不隐藏

8)ng-if控制元素是否“存在”,true存在、false不存在

ng-else

9)ng-src增强图片路径

    ng-href增强地址

10)ng-class=”类名:true/false”控制类名

11)ng-include=“文件路径”  引入模板  必须用服务器,因为js本身无法读取本地文件

12)ng-disabled表单禁用

  ng-readonly表单只读

    ng-checked单/复选框表单选中

    ng-selected下拉框表单选中

13)ng-model数据双向绑定(必须通过表单元素)

14)ng-init可以初始化模型(Model)也就是$scope

15)事件前加ng:ng-click=“show()”单击   里面参数调用方法

$scope.show=function(){  写具体方法}

 ng-dblclick 双击

 ng-blur失去焦点

ng-mouseout鼠标移开

2、自定义指令

AngularJS允许根据实际业务需要自定义指令,通过angular全局对象下的

directive方法实现。

restrict:"ECMA"  

E:可以当成元素来使用;A:属性;C:类名;M:注释

上面四种使用方式都可以显示template中的内容。

使用M时,必须要有replace:ture,才能显示template中的内容。

使用:E:<tag>; A:<div tag>;C:<div class=”tag”>;M://tag

四、作用域

通常AngularJS中应用(App)是由若干个视图(View)组合成而成的,而视图(View)又都是HTML元素,并且HTML元素是可以互相嵌套的,另一方面视图都隶属于某个控制器(Controller),进而控制器之间也必然会产生嵌套关系。

每个控制器(Controller)又都对应一个模型(Model)也就是$scope对象,不同层级控制器(Controller)下的$scope便产生了作用域。

根作用域$rootScope

通过ng-controller指令可以创建一个子作用域,新建的作用域可以访问其父作用域的数据。

五、过滤器

1、内置过滤器

1)、currency将数值格式化为货币格式

传参:{{price|currency:”¥”}}

2)、date日期格式化,年(y)、月(M)、日(d)、星期(EEEE/EEE)、时(H/h)、分(m)、秒(s)、毫秒(.sss),也可以组合到一起使用。

传参:{{now|date:”yyyy-MM-dd”}

3)、filter在给定数组中选择满足条件的一个子集,并返回一个新数组,其条件可以是一个字符串、对象、函数

$scope.items = ['html', 'css', 'js'];

<li>{{items|filter:'s'}}</li>

选出来含有s的

$scope.students = [

{name: '小红', age: 16},

{name: '小明', age: 16},

{name: '小米', age: 10}

];

<li>{{students|filter:{age: 16}后面必须有空格}}</li>

选出年纪16的

4)、json将Javascrip对象转成JSON字符串。

JSON:仅仅是数据格式,可以跨平台传输,必须用双引号引用key,值不能是函数、undefined、NaN

Javascrip对象:表示类的实例,不能传输,key可以不加引号,值可以是函数、对象、字符串、数字、boolean等。

5)、limitTo取出字符串或数组的前(正数)几位或后(负数)几位

<li>{{items|limitTo:-1}}</li>    从右边截取1个

6)、lowercase将文本转换成小写格式

7)、uppercase将文本转换成大写格式

8)、number数字格式化,可控制小位位数

转数字的方法:parseInt(str)    允许开头是数字,后面是字母

 Number(str)     不允许任何有字母,都是NaN

过滤器number不能有字母

{{number|number:4}} 保留4位小数

9)、orderBy对数组进行排序,第2个参数可控制方向

<li>{{items|orderBy: ' ':true}}</li>

true就是倒序

<li>{{students|orderBy: 'age': false}}</li>

按照age升序排序

过滤器的结果可以作为下一个过滤器的输入。

2、自定义过滤器

使用{{input|capitalize}}

function中的input参数就是使用这个过滤器的输入

六、依赖注入

所谓依赖注入是指在运行时自动查找依赖关系,然后将查找到依赖传递给使用者的一种机制。

七、服务

服务要依赖controller

App.controller('DemoController',['$scope', ‘$loctiaon’,function ($scope,$location)

1、内置服务

1)、$location是对原生Javascript中location对象属性和方法的封装。

console.log(location)

host:"localhost"  hostname:"localhost"   主机名(服务器名)

href:http://localhost/location.html整个地址(绝对路径)

hash:""锚点(#之后的内容)

origin:"http://localhost"   跨域

pathname:"/location.html"  去掉localhost之后的地址

port:""  端口(80默认不显示)      search:””   ?后面传输的数据

protocol:"http:"  协议

跨域:协议不同、端口不同、域名不同(三者任意一种)

$scope.absUrl = $location.absUrl();   整个地址(绝对路径)

$scope.url = $location.url();          锚点(#之后的内容)

$scope.host = $location.host();       主机名(服务器名)

$scope.search = $location.search();    锚点上?后面传输的数据(js不能)

$scope.hash = $location.hash();      锚点上的锚点(js不能

$scope.protocol = $location.protocol();  协议

$scope.port = $location.port();        端口(80默认不显示)

2)、$timeout&$interval对原生Javascript中的setTimeout和setInterval进行了封装。

//页面打开3秒后执行$timeout(function () {

$scope.msg = '执行了';}, 3000);

//每隔1秒执行一次var timer = $interval(function () {

$scope.now = new Date;

}, 1000);

 

//取消定时器   $interval.cancel(timer);

3)、$filter过滤器(之前是在view中使用,现在是在model中使用)

$filter(“要使用的九种过滤器中的一种”)(使用过滤器的对象,之前冒号后面的内容)

 4)、$log打印调试信息

5)、$http用于向服务端发起异步请求。

(1)method:“get” Query String Params格,将数据拼接到url传给服务器

url: 'example.php',

method: 'get',  (默认get,可以不写)

headers: {

'Content-Type': 'application/x-www-form-urlencoded'

},

params: { // get 参数必须用params,相当于把数据拼在url?后面

name: 'itcast',

sex: '男'}

}).success(function (info) { });

(2)method:“post” FormData格式,在服务器上传

与get不同的地方:method: 'post',

data: { // post 传参必须用data

    age: 10}

(3) method:“jsonp”跨域

$http({

url: 'jsonp.php?callback=JSON_CALLBACK', 

(或者把callback=JSON_CALLBACK’放在params中)

method: 'jsonp' // 采用JSONP方式

}).success(function (info) {  });

同时还支持多种快捷方式如$http.get()、$http.post()、$http.jsonp。

2、自定义服务

1)、factory方法

app.factory(“服务名”,[依赖的其它服务,function(服务){

         返回函数或对象,对象里面可以包含很多个方法或者对象

function format(){}   一个函数

function say(){}      第二个函数

return {format:format, say:say };

}])

使用:在控制器上加入服务,不加$      factory.format();   factory.say();

 

 

2)、service方法

this.showTime=function(){}

相当于factory方法 return {showTime: function(){}}

使用:服务名.this后面的名字

3)、value方法定义常量

只能定义单一的简单的服务,更像是一个常量

app.value(“服务名”,”值”)

八、模块加载

1、配置块

   1、通过config方法实现对模块的配置,AngularJS中的服务大部分都对应一个“provider”,用来执行与对应服务相同的功能或对其进行配置。

比如$log、$http、$location都是内置服务,相对应的“provider”分别是$logProvider、$httpProvider、$locationPorvider。

下图以$log为例进行演示,修改了配置

下图以$filter为例进行演示,实现相同功能

2、运行块

服务也是模块形式存在的对且对外提供特定功能,前面学习中都是将服务做为依赖注入进去的,然后再进行调用,除了这种方式外我们也可以直接运行相应的服务模块,AngularJS提供了run方法来实现。

 

不但如此,run方法还是最先执行的,利用这个特点我们可以将一些需要优先执行的功能通过run方法来运行,比如验证用户是否登录,未登录则不允许进行任何其它操作。

九、路由

一个应用是由若个视图组合而成的,根据不同的业务逻辑展示给用户不同的视图,路由则是实现这一功能的关键。

SPA(Single Page Application)指的是通单一页面展示所有功能,通过Ajax动态获取数据然后进行实时渲染。 

通常情况下使用Ajax异步请求数据,然后实现内容局部刷新,局部刷新的本质是动态生成DOM,新生成的DOM元素并没有真实存在于文档中,所以当再次刷新页面时新添加的DOM元素会“丢失”,通过单页面应可以很好的解决这个问题。

1、路由

AngularJS是一个纯前端MVC框架,在开发单页面应用时,所有功能都在同一页面完成,所以无需切换URL地址(即不允许产生跳转),但Web应用中又经常通过链接(a标签)来更新页面(视图),当点击链接时还要阻止其向服务器发起请求,通过锚点(页内跳转)可以实现这一点。

实现单页面应用需要具备:

a、只有一页面

b、链接使用锚点

2、使用

1、引入angular-route.js

 

2、实例化模块(App)时,当成依赖传进去(模块名称叫ngRoute)。

3、配置路由模块

4、布局模板

通过ng-view指令布局模板,路由匹配的视图会被加载渲染到些区域。

 

3、路由参数

1)、提供两个方法匹配路由,分别是when和otherwise,when方法需要两个参数,otherwise方法做为when方法的补充只需要一个参数,其中when方法可以被多次调用。

2)、第1个参数是一个字符串,代表当前URL中的hash值。

3)、第2个参数是一个对象,配置当前路由的参数,如视图、控制器等。

a、template 字符串形式的视图模板

b、templateUrl 引入外部视图模板

c、controller 视图模板所属的控制器

d、redirectTo跳转到其它路由

4)、获取参数,在控制中注入$routeParams可以获取传递的参数

总结:1、如果点击<a>标签获取的内容的形式是一样的,templateUrl模板页面可以使用一个:如music.html例子,就只需要一个when(“/:id”),通过$routeParams.id将点击的是哪一个<a>标签作为参数params传递给后端,后端进行判断后将数据返回来,templateUrl模版页面只有一个,控制器controller也只需要一个。

   2、如果点击<a>标签获取的内容的形式是不一样的,templateUrl模版页面不是一样的:如yike例子,每一个<a>标签都要when筛选,对应每一个templateUrl,每一个controller ,$http访问的url也不一样。

$scope.$watch("zidingyi",function(newValue,oldValue, scope) {

      if(newValue<5&&newValue!=""){

      $scope.tishi="最少充值5元。谢谢"

      return

      }

      $scope.tishi="";

      $scope.check=newValue;

     

 }, true);

 

$rootScope全局作用域

$SCOPE

$scope在angularjs中,你可以把它理解成作用域,每个不同的controller,都具有它不同的作用域,所以 controller不同,他们的scope是不同的,那么,如果我们想象js那样,做一个全局变量该怎么办呢?这就要说 到rootScope了。

$ROOTSCOPE

$rootScope就相当于一个全局作用域,所以我们保存在其中的东西是全局性的,在任一controller之中都能够使用。

scope是html和单个controller之间的桥梁,数据绑定就靠他了。rootscope是各个controller中scope的桥梁。 用rootscope定义的值,可以在各个controller中使用。

RootScope定义的值可以在各个Controller中使用,这就是它与Scope的主要区别,Scope定义的值只能在其所在的Controller中使用。

<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<script src="//apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
</head>
<body>


<div ng-controller="myCtrl">
<ul>
    <li ng-repeat="x in names">{{x}}</li>
</ul>
    <p>myCtrl中可以显示使用$rootScope定义的lastname的值:{{lastname}}</p>
    <p>myCtrl中不可以显示使用$scope定义的names2的值:{{names2[0]}}</p>
</div>

<div ng-controller="myCtrl2">
<ul>
    <li ng-repeat="x in names2">{{x}}</li>
</ul>
    <p>myCtrl2中也可以显示使用$rootScope定义的lastname的值:{{lastname}}</p>
    <p>myCtrl2中也不可以显示使用$scope定义的names的值:{{names[0]}}</p>
</div>


<script>
var app = angular.module('myApp', []);
 
app.controller('myCtrl', function($scope,$rootScope) {
    $scope.names = ["Emil", "Tobias", "Linus"];
    $rootScope.lastname = "Refsnes";
});
app.controller('myCtrl2', function($scope) {
    $scope.names2 = ["Emil2", "Tobias2", "Linus2"];
});
</script>
    
</body>
</html>

$injector注入依赖

 

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

app.factory("game",function(){
	return {
		title:"StarCraft"
	}
});
//创建一个injector 参数为绑定的模板  会返回一个injector对象
//通过返回的对象你可以调用模板里面的各种服务
angular.injector(["myApp"]).invoke(function(game){
	alert(game.title);
})

app.controller("AppController",function($scope,game){
	$scope.title = game.title;
});
var app = angular.module("myApp",[]);

app.factory("game",function(){
	return {
		title:"StarCraft"
	}
});
//创建一个injector 参数为绑定的模板  会返回一个injector对象
//通过返回的对象你可以调用模板里面的各种服务
//这种做法会导致所有的当前的模板下面的控制器都会有这个服务  就是弹出game.title  
//如非特殊场景,不建议使用
angular.injector(["myApp"]).invoke(function(game){
	alert(game.title);
})

app.controller("AppController",function($scope,game){
	$scope.title = game.title;
});

app.controller("OtherController",function($scope,$injector) {
	//$injector 服务在angularJS中已经有了  就不需要使用  angular.injector(["myApp"])显示绑定了
	$injector.invoke(function(game){
		$scope.title = game.title;
		alert(game.title);
	});
});

 

get与has
①has方法的作用是从注册的列表查找对应的服务,如果找到返回true,否则返回false;它的调用格式如下:

injector.has(name)

②get方法的作用是返回指定名称的服务实例,获取到服务的实例对象后,就可以直接调用服务中的属性和方法,它的调用格式如下:

injector.get(name)

invoke方法
invoke方法是一个功能强大的方法,它做常用的场景就是执行自定义函数。除此之外,在执行函数时,还能传递变量给函数本身,他的调用格式如下:

injector.invoke(fn,[self],[locals])

在上述代码中,injector为获取$injector对象,参数fn为需要执行的函数名称,可选项参数self是一个对象,表示用于函数中this变量,可选参数locals也是一个对象,它能为函数中变量名的传递提供方法支持。

 

 

 

 

自定义服务

 

  1. Factory
  2. Service
  3. Provider

factory是普通function,而service是一个构造器(constructor),这样Angular在调用service时会用new关键字,而调用factory时只是调用普通的function,所以factory可以返回任何东西,而service可以不返回.

 

angular里的service是一个单例对象,在应用生命周期结束的时候(关闭浏览器)才会被清除。而controllers在不需要的时候就会被销毁了。

factory是angular里的一种service.

Angular里面创建service最简单的方式是使用factory()方法。

在service里面当我们仅仅需要的是一个方法和数据的集合且不需要处理复杂的逻辑的时候,factory()是一个非常不错的选择。

注意:需要使用.config()来配置service的时候不能使用factory()方法

service()通过构造函数的方式让我们创建service,我们可以使用原型模式替代javaScript原始的对象来定义service。

1、factory

factory方式创建的服务,作用就是返回一个有属性有方法的对象。相当于:var f = myFactory();

//创建模型

var app = angular.module('myApp', []);

//通过工厂模式创建自定义服务

app.factory('myFactory', function() {

var service = {};

//定义一个Object对象'

service.name = "张三";

var age;

//定义一个私有化的变量

//对私有属性写getter和setter方法

service.setAge = function(newAge){

age = newAge;

}

service.getAge = function(){

return age;

}

return service;

//返回这个Object对象 });

//创建控制器

app.controller('myCtrl', function($scope, myFactory) {

myFactory.setAge(20);

$scope.r =myFactory.getAge();

alert(myFactory.name);

}); 

2、service

通过service方式创建自定义服务,相当于new的一个对象:var s = new myService();,只要把属性和方法添加到this上才可以在controller里调用。

<div class="alert alert-danger" ng-app="myApp" ng-controller="myCtrl">
        {{a}}+{{b}}={{c}}
</div>
<script>
    //自定义模块1,
    angular.module('common', []).service('addition', function () {
        this.add = function (a, b) {
            return a + b;
        }
    });
    //自定义模块2,依赖于模块一
    var app = angular.module('myApp', ['common']);
    app.controller('myCtrl', function ($scope, addition) {
        $scope.a = 3;
        $scope.b = 4;
        $scope.c = addition.add($scope.a, $scope.b);
    });
</script>
 

3、provider

provider

provider是他们的老大,上面的几乎(除了constant)都是provider的封装,provider必须有一个$get方法,当然也可以说provider是一个可配置的factory

var app = angular.module('app', []);
 
app.provider('movie', function () {
  var version;
  return {
    setVersion: function (value) {
      version = value;
    },
    $get: function () {
      return {
          title: 'The Matrix' + ' ' + version
      }
    }
  }
});
 
app.config(function (movieProvider) {
  movieProvider.setVersion('Reloaded');
});
 
app.controller('ctrl', function (movie) {
  expect(movie.title).toEqual('The Matrix Reloaded');
});

//注意这里config方法注入的是movieProvider,上面定义了一个供应商叫movie,但是注入到config中不能直接写movie,
因为前文讲了注入的那个东西就是服务,是供应商提供出来的,而config中又只能注入供应商(两个例外是$provide和$injector),
所以用驼峰命名法写成movieProvider,Angular就会帮你注入它的供应商。

 

 

1) 用 Factory 就是创建一个对象,为它添加属性,然后把这个对象返回出来。你把 service 传进 controller 之后,在 controller 里这个对象里的属性就可以通过 factory 使用了。

 

2) Service 是用"new"关键字实例化的。因此,你应该给"this"添加属性,然后 service 返回"this"。你把 service 传进 controller 之后,在controller里 "this" 上的属性就可以通过 service 来使用了。

angular中 value和constant

angularJS可以通过constant(name,value)和value(name,value)对于创建服务也是很重要的。

相同点是:都可以接受两个参数,name和value。

区别:

1.constant(name,value)可以将一个已经存在的变量值注册为服务,并将其注入到应用的其他部分中。其中,name为注册的常量的名字,value为注册的常量的值或对象。

2.value(name,value)的name同样是需要注册的服务名,value将这个值将作为可以注入的实例返回。

它们最大的区别是:常量可以注入到配置函数中,而值不行。
通常情况下,可以通过value()来注册服务对象或函数,用constant()来配置数据。

 

value也是angular.Module中的方法value(name, object);其中name是service的名称,object是服务器实例对象,这个时候我们就可以把上边的代码修改正成这样

<!doctype html>
<html>
	<head>
		<script src="angular.min.js" type="text/javascript"></script>
		<script type="text/javascript">
		var app = angular.module('myapp',[])
		.value('testvalue','word');
		app.controller('mytest',function($scope,testvalue){
			$scope.test="hello "+ testvalue;
		});
		</script>
		<title>learing argularjs--widuu</title>
	</head>
	<body ng-app='myapp' ng-controller='mytest' >
	<input ng-model='test'>{{test}}
	</body>
</html>

constant也是angular.Module中的方法constant(name, object);其中name是常量的名称,而object是常量的值

 

<!doctype html>
<html>
	<head>
		<script src="angular.min.js" type="text/javascript"></script>
		<script type="text/javascript">
		var app = angular.module('myapp',[])
			.value('testvalue','widuu')
			.constant('count',23)
			.service('testservice',
				function(testvalue,count){
					this.lable = function(){
						return "this will output:hello "+testvalue+",age is "+count;
					}
				}
			);
		app.controller('mytest',function($scope,testvalue,testservice){
			$scope.test = "hello "+ testvalue;
			$scope.output = testservice.lable();
		});
		</script>
		<title>learing argularjs--widuu</title>
	</head>
	<body ng-app='myapp' ng-controller='mytest' >
	<input ng-model='test'>{{test}}
	</p>
		{{output}}
	</body>
</html> 

 

 

$window和$location

$location

$location服务解析浏览器地址中的url(基于window.location)并且使url在应用程序中可用。将地址栏中的网址的变化反映到$location服务和$location的变化反映到浏览器地址栏。

公开浏览器地址栏中的当前网址,这样就可以:

1.观察和监听网址。

2.改变网址。

与浏览器url同步当用户:

1.改变地址栏的值。

2. 单击“后退”或“前进”按钮(或单击“历史链接”)。

3.点击链接。

表示一组方法(协议、主机、端口、路径、搜索、哈希值)的网址对象。

依赖:$rootElement

方法

absUrl();

只能getter,返回的是完整的url。

url([url],[replace]);

getter/setter,返回当前url路径(当前url#后面的内容,包括参数和哈希值)。

protocol();

只能getter,返回当前url的协议(比如http,https)。

host();

只能getter,返回当前url的主机名。

port();

只能getter,返回当前url的端口号。

path([path]);

getter/setter, 返回当前url的子路径(也就是当前url#后面的内容,不包括参数)。

search(search,[paramValue]);

getter/setter,返回当前url的参数的序列化json对象。

hash([hash]);

getter/setter,返回当前url的哈希值。

replace();

如果被调用,当前$digest过程中所有$location的变化将取代当前的历史记录,而不是增加新的历史记录。

state([state]);

返回当前url的历史状态对象(不包括任何参数)。

调用一个参数并且返回$location时改变历史状态对象。

事件

$locationChangeStart

在url将要被改变时广播。可以使用preventDefault取消默认事件。

参数:

angularEvent:合成事件对象。

newUrl:新的url。

oldUrl:改变前的url。

newState:新的历史状态对象。

oldState:改变前的历史状态对象。

$locationChangeSuccess

在url成功的完成变化后广播。

参数:

angularEvent:合成事件对象。

newUrl:新的url。

oldUrl:改变前的url。

newState:新的历史状态对象。

oldState:改变前的历史状态对象。

 angular.module('Demo', [])
     .controller('testCtrl',["$location","$scope",testCtrl]);
     function testCtrl($location,$scope) {
        var url = "http://example.com:8080/#/some/path?foo=bar&baz=xoxo#hashValue";
        $location.absUrl();// http://example.com/#/some/path?foo=bar&baz=xoxo#hashValue
        $location.url();// some/path?foo=bar&baz=xoxo
        $location.protocol();// http
        $location.host();// example.com
        $location.port();// 8080
        $location.path();// /some/path
        $location.search();// {foo: 'bar', baz: 'xoxo'}
        $location.search('foo', 'yipee');
        $location.search();// {foo: 'yipee', baz: 'xoxo'}
        $location.hash();// #hashValue
        $scope.$on("$locationChangeStart", function () {
          //监听url变化,在变化前做想要的处理
        });
        $scope.$on("$locationChangeSuccess", function () {
          //监听url变化,在变化后做想要的处理
        });
     }

$location在日常开发中是很有用的,特别是$locationChangeStart和$locationChangeSuccess,在做是否登录判断的时候配合拦截器使用,根据拦截器返回的状态,监听url变化并在需要登录的时候退出到登录页面。

$window

一个浏览器窗口对象的引用。它是一个全局对象,在window中是全局可用的,但是它导致一些问题。在Angular中也经常通过$window服务提到它,因此它可以被重写、删除及测试。

$window对象可以用来获取浏览器窗口各项属性(如窗口高度宽度、浏览器版本等等)。

 angular.module('Demo', [])
     .controller('testCtrl',["$window",testCtrl]);
     function testCtrl($window) {
         $window === window;
     }
$window.location.href跳转页面

 

 

 

$interval和$timeout

1. 先将$interval,$timeout,作为参数注入到controller中,

例如rds.controller('controllerCtrl', ['app', '$scope','$http','$routeParams','$filter','$location','$interval','$timeout',

    function (app, $scope,$http,$routeParams,$filter,$location,$interval,$timeout) {
2.在需要用的地方写上该方法 例如  $scope.timer = $interval( function(){
    $scope.backup("1");
  }, 10000);
一开始以为是把需要调用的方法直接写在function(){}的位置,发现方法走到定时器时直接执行了该方法并没有循环执行,后来发现需要把需要调用的方法写在function内,10000表示10秒循环一次.如果要定义循环次数 只需要写成如下这样 $scope.timer = $interval( function(){
    $scope.backup("1");
  }, 10000,3); 3代表循环3次就自动停止循环了.
3.终止定时器 $interval.cancel($scope.timer);
4.$timeout的用法也类似 ,只是$timeout是延迟多少秒后循环一次,而$interval是每隔多少秒循环一次,如果不终止就一直循环
timer = $timeout(function(){
    $scope.processed = false;
},500);

 

angular route路由

1、引入

<script src="https://cdn.bootcss.com/angular.js/1.7.0/angular.min.js"></script>

<script src="https://cdn.bootcss.com/angular.js/1.7.0/angular-route.min.js"></script>

2、依赖注入

angular.module('routingDemoApp',['ngRoute'])

3、配置

.config(['$routeProvider', function($routeProvider){

$routeProvider

.when('/',{template:'这是首页页面'})

.when('/computers',{template:'这是电脑分类页面'})

.when('/printers',{template:'这是打印机页面'})

.otherwise({redirectTo:'/'}); }]);

4、传参数   $routeParams

myapp.config(function ($routeProvider) {

   $routeProvider.when("/cel/:sub",{//传参数

    templateUrl:"cel.html",

    controller:"celCtrl"

   })

  });

myapp.controller("celCtrl",function ($scope,$routeParams) {

  //根据传过来的参数给输入框赋值

  var param = $routeParams["sub"];

  if(param=="a"){

   $scope.mname="我想提建议...";

  }else if(param=="b"){

   $scope.mname="我想购买..."

  }

 });

<li><a href="#cel/a" rel="external nofollow" >告诉我们</a></li>

  <li><a href="#cel/b" rel="external nofollow" >询价</a></li>

 

 

angular-translate(国际化模块)

1、引入(两个)

angular-translate.min.js

angular-translate-loader-static-files.min.js

1. angular-translate.min.js 是angular官方提供的国际化模块; 
2. angular-translate-loader-static-files.min.js 是用来读取本地文件的模块,

2、依赖注入

var soccer=angular.module('soccer',['pascalprecht.translate']);

3、配置

soccer.config(['$translateProvider',function($translateProvider){
       var lang = window.localStorage.lang||'cn';    //通过window.localStorage.lang找到用户选择的语言
       $translateProvider.useStaticFilesLoader({
    files: [{
      prefix: '/Content/Soccer/js/i18n/',//语言包路径
      suffix: '.json'   //语言包后缀名
    }]
  });
  $translateProvider.fallbackLanguage('en-us');//默认加载语言包
  $translateProvider.useStaticFilesLoader();

  $translateProvider.preferredLanguage(lang);//存储用户上一次选择的语言,如果用户是第一次范围,默认显示中文
}]);

<span translate="login_title"></span>

 

angular.module('myApp', [ 'pascalprecht.translate', ]) .config(function ($translateProvider) {

let lang;

if (window.localStorage.lang === undefined || window.localStorage.lang === 'undefined') {

lang = 'en'

} else {

lang = window.localStorage.lang;

}

$translateProvider.preferredLanguage(lang);

$translateProvider.useStaticFilesLoader({

prefix: 'src/app/i18n/',

suffix: '.json'

});

});

window.localStorage.lang获取缓存语言,如果没有设置为English,translateProvider.preferredLanguage(lang)告诉 angular.js 哪种语言是默认已注册的语言,$translateProvider.useStaticFilesLoader用于读取本地json文件,prefix代表文件的路径前缀,suffix代表文件后缀,

  • 如果用户上次访问了中文站, window.localStorage.lang=ch,加载 /i18n/ch.json 文件
  • 如果用户第一次访问, window.localStorage.lang=undefined ,默认加载 /i18n/en.json 文件

4、controller中引$translate

angular.module('myApp').controller('LanguageSwitchingCtrl', ['$scope', '$translate', function (scope, $translate) {
    scope.switching = function(lang){
        $translate.use(lang);
        window.localStorage.lang = lang;
        window.location.reload();
    };
    scope.cur_lang = $translate.use();
}]);

http://yijiebuyi.com/blog/3b55056c87b73ba606c19e9338dca679.html

https://blog.csdn.net/sinat_34798463/article/details/52277483

 

angular.copy() 和angular.extend

复制一个对象或者一个数组(好吧,万物皆对象,数组也是一个对象)。
1> 如果省略了destination,一个新的对象或数组将会被创建出来;
2> 如果提供了destination,则source对象中的所有元素和属性都会被复制到destination中;
3> 如果source不是对象或数组(例如是null或undefined), 则返回source;
4> 如果source和destination类型不一致,则会抛出异常。 注意:这个是单纯复制覆盖,不是类似继承。

使用方法:

angular.copy(source, [destination]);

source:要被拷贝的对象

destination:要被拷贝去的目的地

 

$scope.master = angular.copy(user);

 

  angular.extend(dst,src)

              src:源对象

              dst:被拓展的对象

              用src拓展dst,返回拓展后的对象(后覆盖前)。

 

angular.module("extendApp", [])

.controller("extendController", function($scope)

{

$scope.baby =

{

cry : function()

{

console.log("I can only cry!");

}

}

$scope.adult =

{

earn : function()

{

console.log("I can earn money!");

},

lover:

{

love:function()

{

console.log("I love you!");

}

}

}

$scope.human = {}

$scope.hehe = "hehe ";

$scope.extend = function()

{

angular.extend($scope.human, $scope.baby, $scope.adult);

$scope.human.cry();

$scope.human.earn();

<!-- 注意,这里修改了lover对象的love()方法,由于extends()方法不是深复制的,$scope.human

和$scope.adult其实引用的是同一个对象-->

$scope.human.lover.love = function()

{

console.log("I hate you!");

}

<!-- 这两行都会输出“I hate you !",可怜的adult对象,

他把自己的lover分享给了human! -->

$scope.human.lover.love();

$scope.adult.lover.love();

}});

$on、$emit和$broadcast以及$stateChangeStart和$locationChangeStart

$scope与$scope之间的关系,$scope与$rootScope之间的关系

要理解Angular的事件机制,首先需要了解$scope与$scope之间的关系以及$scope与$rootScope之间的关系。$rootScope是唯一真神,是万域起源,是所有$scope的最终祖先。而$scope与$scope之间可能的关系包括父子关系和兄弟关系。
 

$scope与$rootScope都有 $on、$emit和$broadcast

 

AngularJS中的作用域有一个非常有层次和嵌套分明的结构。其中它们都有一个主要的$rootScope(也就说对应的Angular应用或者ng-app),然后其他所有的作用域部分都是继承自这个$rootScope的,或者说都是嵌套在主作用域下面的。很多时候,你会发现这些作用域不会共享变量或者说都不会从另一个原型继承什么。

那么在这种情况下,如何在作用域之间通信呢?其中一个选择就是在应用程序作用域之中创建一个单例服务,然后通过这个服务处理所有子作用域的通信。

在AngularJS中还有另外一个选择:通过作用域中的事件处理通信。但是这种方法有一些限制;例如,你并不能广泛的将事件传播到所有监控的作用域中。你必须选择是否与父级作用域或者子作用域通信。

$on、$emit和$broadcast使得event、data在controller之间的传递变的简单。

  1. $emit只能向parent controller传递event与data
  2. $broadcast只能向child controller传递event与data
  3. $on用于接收event与data

angular的路由跳转的监听$rootScope.$on

使用angular来做项目时,习惯性的使用第三方路由插件ui-router配置路由。每一个状态都对应着一个页面,

因此对路由状态改变的监听也变的十分重要。

可以使用:$rootScope.$on(…….)监听

$stateChangeStart: 表示路由切换开始      参数 :event,next,current]

$stateNoFound:没有发现           参数: 

$stateChangeSuccess:切换成功      参数:event,current,previous

$stateChangeError:切换失败          参数:event,msg

$locationChangeStart:当$location.path或$location.url发生变化时触发            参数:event,msg

$locationChangeSuccess:当$location.path或$location.url发生成功后触发          参数:event,msg

回调函数的参数解释:

event:当前事件的信息

toState:目的路由状态

toParams:传到目的路由的参数

fromState:起始路由状态

$rootScope.$on('$stateChangeStart',function(event,toState,toParams,fromState,fromParams){
    //tab的状态的改变
    localStorage['from_idea']=fromState.name;//获得上一级路由,存储在localStorage中
});

路线更改事件 $ROUTECHANGESTART 与 $LOCATIONCHANGESTART

$routeChangeStart属于$route模块,使用将要改变的路由和当前路由对比,在没有跳转之前

  参数包括 function(event, next, current) 

function locationChangeStart(event, newUrl) {
        $log.log('locationChangeStart');
        $log.log(arguments);
 
        var ret = $window.confirm('Are you sure to give it up? ');
        if (ret) {
            locationChangeStartOff(); //Stop listening for location changes or you can do others
            $location.path(newUrl);
            return;
        }
        event.preventDefault();
        return;
    }
 

  $locationChangeStart属于$location模块,使用在路由已经改变之后

  参数包括 function(event, newUrl, oldUrl)

$broadcast$emit用于发布事件,他们将事件名称和事件内容发布出去

 

 

$on用于订阅事件,事件名称是订阅的唯一标识

使用$on订阅事件时会返回一个函数,而此函数就是用来退订事件的方法

// 订阅事件返回用于退订事件的函数

var deregister = $scope.$on('EVENT_NAME', function(event, args) { // balabala });

// 退订事件 deregister();

$ stateChangeStart和$routeChangeStart差不多,似乎$ stateChangeStart更好

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值