Angular入门
初识Angular,理解它的基本设计原理可以更好的把握Angular。看了慕课网大漠穷秋老师的视频,总结一下。下面的源码也来自慕课网,可以下载到。
1 Angular的四大特点
MVC、模块化、双向数据绑定、指令系统。
2 MVC
2.1 什么是MVC,为什么要用MVC?
MVC:模型、视图、控制器,互联网的三层架构:视图负责客户端与用户交互,控制器负责中间业务逻辑的处理,互通了视图和数据,模型用语对数据的增删改查。
在大型项目中,需要多人合作开发,而每个人只是负责其中一个功能快,MVC划分了视图、控制和模型,让指责更加清晰,也提高了复用性,同一个视图可以调用不同的模型实现样式相同内容不一的页面(eg:不同班级的课程表),不同的视图也可以调用同一个模型实现同一份数据的不同展示(eg:用三点图/折线图/雷达图... 展示同一份报告)。功能划分明确,也便于维护。
以上,NVC是为了模块化和复用,MVC只是手段,目标比手段更重要。
2.2 前端实现MVC有哪些困难
实现MVC思路是很清晰的,控制器就是大脑,负责把模型中的数据交给视图来展现,交互过程中又通过大脑来操作数据,改变视图。
然而在前端,有一些情况需要去考虑:
对DOM的操作,必须保证是在DOM加载完成之后执行,如何保证,MVC并未给出解决方案。
资源文件之间经常会有依赖关系,如何确保依赖关系的正确性,需要程序员自己解决。
js的原型继承也给前端编程带来很多困难
2.3 Angular如何实现MVC
2.3.1 在Angular中,M、V、C分别是什么?
{{greeting.text}},Angular
js/angular-1.3.0.js 是Angular的源文件
HelloAngular_MVC.js:
function HelloAngular($scope) { $scope.greeting = { text: 'Hello' };}
视图很好理解,ng-controller="HelloAngular"指定了控制器,{{greeting.text}}指定了模型,在js代码中可以了解控制器是如何控制模型的。$scope指明了作用域,这里的作用域是div。
2.3.2 Controller的使用误区
1.不要复用controller,需要复用的地方又service实现,不良写法:
{{greeting.text}},Angular test1 {{greeting.text}},Angular test2 通用
Controller:
function CommonController($scope){ $scope.commonFn=function(){ alert("这里是通用功能!"); };}function Controller1($scope) { $scope.greeting = { text: 'Hello1' }; $scope.test1=function(){ alert("test1"); };}function Controller2($scope) { $scope.greeting = { text: 'Hello2' }; $scope.test2=function(){ alert("test2"); }}
2.不要用controller操作DOM,因为controller操作DOM的代价很昂贵,需要重绘或者重新布局,angular中通过指令操作DOM。
3.数据的格式化操作由表单控件完成,不要用controler做数据格式化操作。
4.$filter服务可以做数据过滤,不需要用controller做数据过滤。
5.不要互相调用controller,而是通过事件来调用。
2.3.3 如何复用Model
跑一下下面的代码吧:
{{greeting.text}},Angular
Root scope MyEvent count: {{count}} $emit('MyEvent') $broadcast('MyEvent') Middle scope MyEvent count: {{count}} Leaf scope MyEvent count: {{count}}
Scope2.js:
function EventController($scope) {
$scope.count = 0;
$scope.$on('MyEvent', function() {
$scope.count++;
});
}
$emit('MyEvent')可以控制控制器中事件控制本级和上级模型,$broadcast('MyEvent')可以控制控制器中事件控制本级和下级模型,说明:ng-repeat表明了元素中内容重复的次数。angular.element($0).scope()可以对$scope进行调试。$scope的生命周期:创建-》注册监控-》检测模型变化-》观察模型是否脏-》销毁## 3 模块化### 3.1 没有模块化的项目组织思考一下,我们现在会如何开发一个项目呢?一个项目会有多个文件,这些文件又该如何组织呢,一种方法是:js文件放入scripts文件夹下,css文件放在styles文件夹下,img文件放在images文件夹下,资源包放在node_modules类似的文件夹下,嗯,似乎看起看很工整,但是想一下,这样是否存在问题呢?1. 实现逻辑时,函数变量会挂在全局,这样合理吗?1. 这么多的功能,是否需要功能划分呢?1. 每个控制器都要单独存入一个文件嘛?这样也太多了吧1. 把多个控制器写在同一个文件,多人开发的时候同时处理一个文件很容易产生冲突的1. 文件之间如果存在依赖关系,该如何解决呢?比如在开发多页应用时,要用到路由机制,路由需要调用控制器和视图,如何保证路由执行的时候,控制器和视图及其依赖的服务加载完成了呢?这里需要借助模块化来解决问题。### 3.2 有模块化的项目组织#### 3.2.1 何为模块,模块就是实现一定功能的程序集合,这个集合中包括控制、视图、服务、过滤等。#### 3.2.2 angular中的模块实现
{{greeting.text}},Angular
NgModule1.js:
var helloModule=angular.module('HelloAngular', []);
helloModule.controller('helloNgCtrl', ['$scope', function($scope){
$scope.greeting = {
text: 'Hello'
};
}]);
#### 3.2.3 模块化优势这样,便解决了1.变量污染全局的问题,并且可以2.按照功能划分模块。3.4.当同一个文件加载多个控制器时,可以通过前端强大的自动化工具grunt来实现,助力了模块化的开发。5.通过依赖注入可以解决资源依赖的问题。#### 3.3.4 模块化实现首先先了解一个项目的目录,再具体讲解如何实现依赖注入。以BookStore 为例说明:1. framework存放了资源文件1. tpls:templates,存放模版文件,主要用于视图的管理1. index.htm为入口文件跑一下应用:来解析一下文件:首先看入口文件 index.html:
BookStore
主要是对一些资源文件的加载,这里通过路由控制加载视图 app.js:
var bookStoreApp = angular.module('bookStoreApp', [
'ngRoute', 'ngAnimate', 'bookStoreCtrls', 'bookStoreFilters',
'bookStoreServices', 'bookStoreDirectives'
]);
bookStoreApp.config(function($routeProvider) {
$routeProvider.when('/hello', {
templateUrl: 'tpls/hello.html',
controller: 'HelloCtrl'
}).when('/list',{
templateUrl:'tpls/bookList.html',
controller:'BookListCtrl'
}).otherwise({
redirectTo: '/hello'
})
});
bookStoreApp后面[]中指明了bookStoreApp依赖的模块,在加载时保证了依赖模块加载完之后才运行本模块,下面的配置项说明了哪个url链接应该对应哪个控制器管理的哪个视图,主要when方法和otherwise方法,otherwise方法说明未指明路由是默认定向到/hello路由。看一下这个控制器是怎样的 controllers.js:
var bookStoreCtrls = angular.module('bookStoreCtrls', []);
bookStoreCtrls.controller('HelloCtrl', ['$scope',
function($scope) {
$scope.greeting = {
text: 'Hello'
};
}
]);
bookStoreCtrls.controller('BookListCtrl', ['$scope',
function($scope) {
$scope.books =[
{title:"《Ext江湖》",author:"大漠穷秋"},
{title:"《ActionScript游戏设计基础(第二版)》",author:"大漠穷秋"},
{title:"《用AngularJS开发下一代WEB应用》",author:"大漠穷秋"}
]
}
]);
其它的文件只是给了框架,为了给出一个项目的架构。directives.js:
var bookStoreDirectives = angular.module('bookStoreDirectives', []);
bookStoreDirectives.directive('bookStoreDirective_1', ['$scope',
function($scope) {}
]);
bookStoreDirectives.directive('bookStoreDirective_2', ['$scope',
function($scope) {}
]);
filters.js:
var bookStoreFilters = angular.module('bookStoreFilters', []);
bookStoreFilters.filter('bookStoreFilter_1', ['$scope',
function($scope) {}
]);
bookStoreFilters.filter('bookStoreFilter_2', ['$scope',
function($scope) {}
]);
services.js:
var bookStoreServices = angular.module('bookStoreServices', []);
bookStoreServices.service('bookStoreService_1', ['$scope',
function($scope) {}
]);
bookStoreServices.service('bookStoreService_2', ['$scope',
function($scope) {}
]);
至此,应该了解了一个简单项目的架构和依赖管理。## 4 双向数据绑定### 4.1 什么是双向数据绑定终于讲到双向数据绑定了,这个神奇的东西到底是什么?就是视图到模型,模型到视图的双向绑定,模型和视图达成了同步。### 4.2 双向数据绑定如何实现#### 4.2.1 从$scope -> view的单向绑定MVC通常的思路是,将模型的数据展示在视图上,那么。如何实现从模型到视图的绑定呢?我们似乎实现过从模型到视图的绑定。
,Angular
HelloAngular_MVC.js:
function HelloAngular($scope) {
$scope.greeting = {
text: 'Hello'
};
}
如果使用{{greeting.text}},在AngularJS使用数据替换模板中的花括号,其未被渲染的模板可能会被用户看到。狂刷屏幕,视图上会暂态出现{{greeting.text}},Angular。还有另一种实现方式:ng-bind="greeting.text"。数据加载完成之前用户就不会看到任何内容。模型到视图不仅可以控制内容,还可以控制样式:
{{messageText}} Simulate Error Simulate Warning
NgClass.css:
.error {
background-color: red;
}
.warning {
background-color: yellow;
}
NgClass.js:
var myCSSModule = angular.module('MyCSSModule', []);
myCSSModule.controller('HeaderController', ['$scope',
function($scope) {
$scope.isError = false;
$scope.isWarning = false;
$scope.showError = function() {
$scope.messageText = 'This is an error!';
$scope.isError = true;
$scope.isWarning = false;
};
$scope.showWarning = function() {
$scope.messageText = 'Just a warning. Please carry on.';
$scope.isWarning = true;
$scope.isError = false;
};
}
])
ng-class实现了从模型到样式数据的控制,ng-class='{error: isError, warning: isWarning},isError为true,则加入error类。还有一些其它的控制,有需求时可以查阅官网。请输入代码#### 4.2.2 从$scope view的双向绑定给一个实例,来实现双向数据绑定我们希望,视图中表单的内容的改变可以影响模型,通过按钮控制的模型的改变可以影响到视图中表单的内容。借助bootstrap实现了以上的布局:
双向数据绑定 邮箱: 密码: 自动登录 获取Form表单的值 设置Form表单的值 重置表单
Form.js:
var userInfoModule = angular.module('UserInfoModule', []);
userInfoModule.controller('UserInfoCtrl', ['$scope',
function($scope) {
$scope.userInfo = {
email: "253445528@qq.com",
password: "253445528",
autoLogin: true
};
$scope.getFormData = function() {
console.log($scope.userInfo);
};
$scope.setFormData = function() {
$scope.userInfo = {
email: 'damoqiongqiu@126.com',
password: 'damoqiongqiu',
autoLogin: false
}
};
$scope.resetForm = function() {
$scope.userInfo = {
email: "253445528@qq.com",
password: "253445528",
autoLogin: true
};
}
}
])通过指令ng-model实现了从$scope view的双向绑定。#### 4.2.3 扩展路由之前讲过用app.js实现页面的控制,但是如果一个页面内部需要局部更新,切换路由,再用$routeProvider实现会很不合适, ui-router提供了页内的路由嵌套。咦?为什么要用页内嵌套路由呢?需要什么信息,使用ajax加载局部更新不就可以了嘛?ajax在加载后页面的url是不会改变的,也就是在加载前和加载后是同一个url,那么我们也就无法定位到ajax加载后的页面,当想把加载后的页面加入书签或者推荐给好友时是无法获得浏览记录的。## 5 指令### 5.1 指令配置项以hello指令为例:
HelloAngular_Directive.js:
var myModule = angular.module("MyModule", []);
myModule.directive("hello", function() {
return {
restrict: 'AEMC',
template: 'Hi everyone!',
replace: true
}
});### 5.1.1 匹配模式restrict说明了匹配模式:
四个hello分别是元素、属性、样式类和注释的匹配模式。### 5.1.2 模版template模版指定了指令的内容。template: 'Hi everyone!'直接指定了模版的内容,如果模版内容很多饿时候在js里面写标签是很痛苦的。`templateUrl: 'hello.html'可以通过指定url来指定一个文件为模版,还可以通过缓存的方式存储复用模版:
var myModule = angular.module("MyModule", []);
//注射器加载完所有模块时,此方法执行一次
myModule.run(function($templateCache){
$templateCache.put("hello.html","Hello everyone!!!!!!");
});
myModule.directive("hello", function($templateCache) {
return {
restrict: 'AECM',
template: $templateCache.get("hello.html"),
replace: true
}
});
### 5.1.3 替换当replace为true时,如果hello中嵌套了内容,hello中的内容会被替换掉,不显示:
这里是指令内部的内容。
如果不想被替换,可以使用transclude:true:
var myModule = angular.module("MyModule", []);
myModule.directive("hello", function() {
return {
restrict:"AE",
transclude:true,
template:"Hello everyone!"
}
});
当指令想要嵌套指令时,这种方式可以不让被嵌套的指令被替代掉。以上大概讲解了一下指令,还有很多指令的内容,在基础入门这里就先介绍这么多。#angularjs#
版权声明
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!