angularjs实际项目开发

最近看了看angularjs,这里记录下,怕自己忘记。

目录

目录架构

路由ui-router

简介:

实例:

架构:

自定义服务

Factory:

5种其他创建方式

Service方式:

架构:

控制器

简介:

实例:

架构:

自定义指令

directive

需要的设置项

常用参数介绍

controller:

作用域:

架构:

过滤器

模板使用:

Js调用:

自定义过滤器:

架构:

表单验证

拦截器


 

实际开发

 

目录架构

Angularjs也是延用了类似mvc的项目结构,view(html页面和模板),controller(js中的控制器模块),service(js中的服务),项目大体结构如下:

1.   controllers该模块(文件夹)下都是项目的controller,作用是将view和service进行绑定与显示。

2.   services该模块(文件夹)下,与服务端接口对接,获取数据。

3.   xxx.html项目的入口文件,里面是所有js、controller、service等汇总文件

4.   xxx.js全局js文件,与路由、拦截器等相关。

5.   filters该模块(文件夹)下,是定义的过滤器(一般是自定义)

6.   directives该模块(文件夹)下,是自定义的指令

路由ui-router

简介:

AngularUI库提供的最有用的库之一便是ui-router。angular-ui-router.js它是一个路由框架,允许你通过状态机
组织接口,而不是简单的URL路由。

 

1.   首先要引用该模块:

 

 

2.   路由要在其他模块开始前执行,在angular的config中进行配置,路由在控制器之上进行。

3.   默认路由

 

 

4.    $stateProvider中的state属性的第一个参数

 

 

 

5.   templateUrl属性获取外部模板,main.tpl是外部的html模板

 

 

6.   controller属性

第一种方式:

 

 

第二种方式:

 

 

7.   在控制器和指令中进行路由跳转

 

 

点击去首页这个超链接,启动to方法,便可到达下面路由,并找到对应内容

 

8.   路由参数设置和$stateParams服务

 

 

 

 

9.   路由定义父子级嵌套

  第一种方式:

Parent属性指定父级路由,子路由中的模板会在父路由的模板中的view视图下进行显示。

 

 

第二种方式:在子路由前加上父路由

 

 

 

 

10.多路由嵌套

如果页面是下面这种布局,常见的路由用法:

 

 

 

 

三个ui-view视图,下面state属性里用views进行多个嵌套,里面可以加templateUrl、controller等属性

 

 

 

点击视频超链接跳转video路由,此时之将right.tpl进行替换

 

 

11.多路由父子嵌套

 

 

 

 

 

 

实例:

<html>

 <head>  

   <title>ui-router</title>

 

   <script type="text/javascript"src="angular.js"></script>

   <script type="text/javascript"src="angular-ui-router.js"></script> 

 </head>

 

 <body >  

   <div ng-app="myApp">       

       <div ui-view></div> <!-- 视图 -->    

   </div> 

 </body>

 

 

 <script type="text/javascript">

   //定义模板,并注入ui-router

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

   //对服务进行参数初始化,这里配stateProvider服务的视图控制

   app.config(["$stateProvider",'$urlRouterProvider',  function ($stateProvider,$urlRouterProvider){     

                   $urlRouterProvider.otherwise('/nv');

       $stateProvider

                   .state("home2",{

           url: '/default',  

           template:'<div>ss......</div>'

       })

                   .state("home3",{

           url: '/nv',  

           template:'<div>nv......</div>'

       })

                   .state("home",{

           url: '/main',  

           templateUrl:'main.tpl'

       })

                           

   }]); 

        

 

 </script>

 

</html>

 

架构:

 

我们将路由放入一个类似XXX router.js中,并进行引用.

自定义服务

Factory:

 

使用angular.module的factory API创建服务,是最常见也是最灵活的方式:
angular.module('myApp.services', [])
.factory('githubService', function() {
var serviceInstance = {};
// 我们的第一个服务
return serviceInstance;
});

 

5种其他创建方式

在AngularJS应用中, factory()方法是用来注册服务的最常规方式,同时还有其他一些API
可以在特定情况下帮助我们减少代码量。
共有5种方法用来创建服务:
qfactory()
qservice()
qconstant()
qvalue()
qprovider()

 

Service方式:

 

 

架构:

我们将自定义服务放入一个类似XXXService.js中,并进行引用。可以设计成总的指令js,也可以每个模块写一个js并放在servicess文件夹下

控制器

简介:

除了孤立作用域外,所有的作用域都通过原型继承而来,也就是说它们都可以访问父级作用
域。如果熟悉面向对象编程,对这个机制应该不会陌生。
默认情况下, AngularJS在当前作用域中无法找到某个属性时,便会在父级作用域中进行查
找。如果AngularJS找不到对应的属性,会顺着父级作用域一直向上寻找,直到抵达$rootScope
为止。如果在$rootScope中也找不到,程序会继续运行,但视图无法更新。
通过例子来看一下这个行为。创建一个ParentController,其中包含一个user对象,再创
建一个ChildController来引用这个对象:
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的$scope对象

实例:

varapp = angular.module('app', []);
app.controller('FirstController', function($scope) {
$scope.message = "hello";
});

架构:

我们将自定义控制器放入一个类似XXXController.js中,并进行引用。可以设计成总的指令js,也可以每个模块写一个js并放在controllers文件夹下

 

自定义指令

directive

directive()这个方法是用来定义指令的可以接受两个参数1. name(字符串)2. factory_function (函数)

angular.application('myApp',[])
.directive('myDirective', function() {
// 一个指令定义对象
return {
// 通过设置项来定义指令,在这里进行覆写
};
});

 

需要的设置项

可能的选项如下所示,每个键的值说明了可以将这个属性设置为何种类型或者什么样的
函数:
angular.module('myApp', [])
.directive('myDirective', function() {
return {
restrict: String,
priority: Number,
terminal: Boolean,
template: String or Template Function:
function(tElement, tAttrs) (...},
templateUrl: String,
replace: Boolean or String,
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(...) { ... }

}
};
});

 

常用参数介绍

restrict是一个可选的参数。它告诉AngularJS这个指令在DOM中可以何种形式被声明。默
认AngularJS认为restrict的值是A,即以属性的形式来进行声明。
可选值如下:
E(元素)
<my-directive></my-directive>
A(属性,默认值)
<div my-directive="expression"></div>
C(类名)
<div class="my-directive:expression;"></div>
M(注释)
<--directive:my-directive expression-->
这些选项可以单独使用,也可以混合在一起使用:
angular.module('myDirective', function(){
return {
restrict: 'EA' // 输入元素或属性
};
});
上面的配置可以同时用属性或注释的方式来声明指令:
<-- 作为一个属性 -->
<div my-directive></div>
<-- 或者作为一个元素 -->
<my-directive></my-directive>

 

 

template参数是可选的,必须被设置为以下两种形式之一:
q 一段HTML文本;
q 一个可以接受两个参数的函数,参数为tElement和tAttrs,并返回一个代表模板的字符
串。 tElement和tAttrs中的t代表template,是相对于instance的。在讨论链接和编译
设置时会详细介绍,模板元素或属性与实例元素或属性之间的区别。
AngularJS会同处理HTML一样处理模板字符串。模板中可以通过大括号标记来访问作用域,
例如{{ expression }}。
如果模板字符串中含有多个DOM元素,或者只由一个单独的文本节点构成,那它必须被包
含在一个父元素内。换句话说,必须存在一个根DOM元素:
template: '\
<div> <-- single root element -->\
<a href="http://google.com">Click me</a>\
<h1>When using two elements, wrap them in a parent element</h1>\
</div>\
另外,注意每一行末尾的反斜线,这样AngularJS才能正确解析多行字符串。在实际生产中,
更好的选择是使用templateUrl参数引用外部模板

 

 

templateUrl是可选的参数,可以是以下类型:
q 一个代表外部HTML文件路径的字符串;
q 一个可以接受两个参数的函数,参数为tElement和tAttrs,并返回一个外部HTML文件
路径的字符串。

 

replace是一个可选参数,如果设置了这个参数,值必须为true,因为默认值为false。默
认值意味着模板会被当作子元素插入到调用此指令的元素内部:
<div some-directive></div>
.directive('someDirective', function() {
return {
template: '<div>some stuff here<div>'
};
});
调用指令之后的结果如下(这是默认replace为false时的情况):
<div some-directive>
<div>some stuff here<div>
</div>
如果replace被设置为了true:
.directive('someDirective', function() {
return {
replace: true // 修饰过
template: '<div>some stuff here<div>'
};
});
指令调用后的结果将是:
<div>some stuff here<div>。

 

 

transclude是一个可选的参数。如果设置了,其值必须为true,它的默认值是false;将transclude设为true后,在模板中加指令ng-transclude,页面上原内容将放入指令的标签中。

transclude:true,
template: '<div class="sidebox">\
<div class="content">\
<h2 class="header">{{ title }}</h2>\
<span class="content" ng-transclude>\
</span>\
</div>\
</div>'
};

 

controller:

controller参数可以是一个字符串或一个函数。当设置为字符串时,会以字符串的值为名字,
来查找注册在应用中的控制器的构造函数:
angular.module('myApp', [])
.directive('myDirective', function() {
restrict: 'A', // 始终需要
controller: 'SomeController'
})
// 应用中其他的地方,可以是同一个文件或被index.html包含的另一个文件
angular.module('myApp')
.controller('SomeController', function($scope, $element, $attrs, $transclude) {
// 控制器逻辑放在这里
});
可以在指令内部通过匿名构造函数的方式来定义一个内联的控制器:
angular.module('myApp',[])
.directive('myDirective', function() {
restrict: 'A',
controller:
function($scope, $element, $attrs, $transclude) {
// 控制器逻辑放在这里
}
});
我们可以将任意可以被注入的AngularJS服务传递给控制器。例如,如果我们想要将$log服
务传入控制器,只需简单地将它注入到控制器中,便可以在指令中使用它了。
控制器中也有一些特殊的服务可以被注入到指令当中。这些服务有:
1. $scope
与指令元素相关联的当前作用域。
2. $element
当前指令对应的元素。
3. $attrs
由当前元素的属性组成的对象。例如,下面的元素:
<div id="aDiv"class="box"></div>
具有如下的属性对象:
{
id: "aDiv",
class: "box"
}

4.$transclude
嵌入链接函数会与对应的嵌入作用域进行预绑定。
transclude链接函数是实际被执行用来克隆元素和操作DOM的函数。

作用域:

 

控制器中作用域关系:

除了孤立作用域外,所有的作用域都通过原型继承而来,也就是说它们都可以访问父级作用
域。

默认情况下, AngularJS在当前作用域中无法找到某个属性时,便会在父级作用域中进行查
找。如果AngularJS找不到对应的属性,会顺着父级作用域一直向上寻找,直到抵达$rootScope
为止。如果在$rootScope中也找不到,程序会继续运行,但视图无法更新。

利用属性的形式是继承隔离,

利用对象的形式是继承不隔离

1.   如果子作用域未自己定义属性,都是继承父作用域,则:父作用域属性改变,子作用域属性也会改变;子作用域属性改变,父作用域属性不改变。

2.   如果子作用域自己定义了属性,则:父作用域属性改变,子作用域属性不会改变;子作用域属性改变,父作用域属性不改变;即父作用域和子作用域只改变自己;

3.   利用js对象传值属性,在父作用域与定义对象及其属性,子作用域未自己定义属性,都是继承父作用域,则:父作用域属性改变,子作用域属性也会改变;子作用域属性改变,父作用域属性也改变。

 

 

4.   利用js对象传值属性,在父作用域与定义对象及其属性,子作用域继承对象并在对象中定义自己的属性,则:父作用域属性改变,子作用域属性不会改变;子作用域属性改变,父作用域属性不改变。

 

指令中作用域的关系:

Directive中的scope属性设置作用域的关系

1.   scope为false时:这也是默认行为,指令中的作用域和控制器中作用域完全共享数据,即控制器中作用域编号,指令中作用域也变化;指令中作用域变化,控制器中也变化。

2.   scope为true时:类似继承行为,及指令中作用域继承控制器中的作用域,具体看控制器中作用域关系中1、2两点。

3.   scope为{ }时:完全隔离,即控制器作用域和指令作用域之间数据隔离,指令和指令作用域之间也数据隔离。

 

@:单项数据绑定,父影响子

 

=:双向数据绑定,父影响子,子影响父

 

&:调用父作用域方法

 

架构:

我们将自定义指令放入一个类似XXX Directive.js中,并进行引用。可以设计成总的指令js,也可以每个模块写一个js并放在directives文件夹下;restrict:'EA' // 一般用AE,templateUrl一般是指定外部模板

 

过滤器

AngularJS有很多实用的内置过滤器,同时也提供了方便的途径可以自己创建过滤器。

模板使用:

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

<!--显示: 123.46 -->
{{ 123.456789 | number:2 }}

Js调用:

在js代码中可以通过$filter来调用过滤器。例如,在js代码中使用lowercase
过滤器:
app.controller('DemoController', ['$scope', '$filter',
function($scope, $filter) {
$scope.name = $filter('lowercase')('Ari');
}]);

 

 

 

 

自定义过滤器:

过滤器本质上是一个会把我们输入的内容当作参数传入进去的函数。
angular.module('myApp.filters', [])
.filter('capitalize',function() {
return function(input) {
// input是我们传入的字符串
if (input) {
return input[0].toUpperCase() + input.slice(1);
}
});
现在,如果想将一个句子的首字母转换成大写形式,可以用过滤器先将整个句子都转换成小
写,再把首字母转换成大写:
<!-- Ginger loves dog treats -->
{{ 'ginger loves dog treats' | lowercase | capitalize }}

 

架构:

我们将自定义过滤器放入一个类似XXXfilter.js中,并进行引用。可以设计成总的过滤器js,也可以每个模块写一个js并放在filters文件夹下。

 

表单验证

Angular中新增了一个ngMessages指令,angular-messages.js,还要告诉Angular将ngMessages作为应用程序的依赖模块引入,就像这样:
angular.module('myApp', ['ngMessages']);

 

<formname="signup_form" novalidate ng-submit="signupForm()"
ng-controller="signupController">

<label>Yourname</label>
<input type="text" placeholder="Name"name="name" ng-model="signup.name" ng-minlength=
3 ng-maxlength=20 required />
<div class="error"ng-messages="signup_form.name.$error">
<div ng-message="required">Make sure you enter yourname</div>
<div ng-message="minlength">Your name must be at least 3characters</div>
<div ng-message="maxlength">Your name cannot be longer than 20characters</div>
</div>
<button type="submit">Submit</button>
</form>

拦截器

拦截器的核心是服务工厂,通过向$httpProvider.interceptors数组中添加服务工厂,在$httpProvider中进行注册。

一共有四种拦截器,两种成功拦截器,两种失败拦截器。

request
AngularJS通过$http设置对象来对请求拦截器进行调用。它可以对设置对象进行修改,或者创建
一个新的设置对象,它需要返回一个更新过的设置对象,或者一个可以返回新的设置对象的promise。
q response
AngularJS通过$http设置对象来对响应拦截器进行调用。它可以对响应进行修改,或者创建
一个新的响应,它需要返回一个更新过的响应,或者一个可以返回新响应的promise。
q requestError
AngularJS会在上一个请求拦截器抛出错误,或者promise被reject时调用此拦截器。
qresponseError
AngularJS会在上一个响应拦截器抛出错误,或者promise被reject时调用此拦截器。

调用模块的.factory()方法来创建拦截器,可以在服务中添加一种或多种拦截器:
angular.module('myApp', [])
.factory('myInterceptor', function($q) {
var interceptor = {
'request': function(config) {
// 成功的请求方法
return config; // 或者 $q.when(config);
},
'response': function(response) {
// 响应成功
return response; // 或者 $q.when(config);
},
'requestError': function(rejection) {
// 请求发生了错误,如果能从错误中恢复,可以返回一个新的请求或promise
return response; // 或新的promise
// 或者,可以通过返回一个rejection来阻止下一步
// return $q.reject(rejection);
},
'responseError': function(rejection) {
// 请求发生了错误,如果能从错误中恢复,可以返回一个新的响应或promise
return rejection; // 或新的promise
// 或者,可以通过返回一个rejection来阻止下一步
// return $q.reject(rejection);
}
};
return interceptor;
});
我们需要使用$httpProvider在.config()函数中注册拦截器:
angular.module('myApp', [])
.config(function($httpProvider) {
$httpProvider.interceptors.push('myInterceptor');
});

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值