MVC介绍
MVC是一种开发模式,由模型(Model)、视图(View)、控制器(Controller)3部分构成. 用一种业务逻辑,数据,界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面.在改进和个性化定制界面及用户交互的同时不需要重新编写业务逻辑. 采用这种开发模式为合理组织代码提供了方便、降低了代码间的耦合度、功能结构清晰可见。
M模型(Model)模型是应用程序的主体部分。模型表示业务数据,或者业务逻辑. 。
V视图(View)视图是应用程序中用户界面相关的部分,是用户看到并与之交互的界面。
C控制器(Controller)控制器工作就是根据用户的输入,控制用户界面数据显示和更新model对象状态。
优点:MVC 式的出现不仅实现了功能模块和显示模块的分离,同时它还提高了应用系统的可维护性、可扩展性、可移植性和组件的可复用性
TIPS:MVVM
MV:可以通过模型到视图传递数据;
VM:视图也可以传递数据;
MVVM属于数据的双向绑定.
模块化简介
使用AngularJS构建应用时是以模块化(Module)的方式组织的,即将整个应用划分成若干模块.每一个模块完成一个特定的子功能,所有的模块按某种方式组织起来,成为一个整体,完成整个系统所要求的功能.采用模块化的组织方式,可以最大程度的实现代码的复用 .
1.定义模块
- 定义应用:
通过为任一HTML标签添加ng-app属性,可以指定一个应用
表示此标签所包裹的内容都属于应用(App)的一部分。 - 定义模块:
- 创建模块: AngularJS提供了一个全局对象angular,在此全局对象下存在若干的方法.
其中angular.module()方法用来定义一个模块。
var app = angular.module('app',[]);
2.创建控制器
控制器作为连接模型和视图的桥梁存在,所以当我们定义好控制器以后就定义好了模型和视图.
第一个参数:控制器的名称,第二页参数:依赖的服务 app.controller('名称'['$scope',function($scope){}]);
app.controller('myController',['$scope',function($scope){
$scope.name = 'pat';
$scope.age = 18;
$scope.course = ['js','css,'h5']
}])
3.绑定模块 ng-app = "模块的名称"
<body ng-app = 'app'>
- 绑定控制器
<body ng-app = 'app'>
<ul ng-controller = 'myController'>
<li>{{name}}</li>
<li>{{age}}</li>
</ul>
</body>
2.内置指令
HTML在构建应用(App)时存在诸多不足之处,AngularJS通过扩展一系列的HTML属性或标签来弥补这些缺陷,所谓指令就是AngularJS自定义的HTML属性或标签,这些指令都是以ng-做为前缀的,例如ng-app、ng-controller、ng-repeat等。
内置指令:
ng-app 指定应用根元素,至少有一个元素指定了此属性。
ng-controller 指定控制器
ng-show控制元素是否显示,true显示、false不显示
ng-hide控制元素是否隐藏,true隐藏、false不隐藏
ng-if控制元素是否“存在”,true存在、false不存在
ng-src增强图片路径
ng-href增强地址
ng-class控制类名
ng-include引入模板
ng-disabled表单禁用
ng-readonly表单只读
ng-checked单/复选框表单选中
ng-selected下拉框表单选中
3.自定义指令
AngularJS允许根据实际业务需要自定义指令,通过angular全局对象下的directive方法实现。
/*通过模块对象的directive方法自定义指令*/
app.directive(‘tag’,function () {
/*返回一个对象,这个对象就是自定义指定的相关内容*/
return{
/*自定义指定的类型*/
restrict:‘ECMA’,
/*自定义模板*/
templateUrl: './head.html’,
/*是否替换原有标签*/
replace:true
/*是否保留标签内容*/
transclude:false
}
})
4.数据绑定
AngularJS是以数据做为驱动的MVC框架,所有模型(Model)里的数据经由控制器(Controller)展示到视图(View)中。 所谓数据绑定指的就是将模型(Model)中的数据与相应的视图(View)进行关联.
AngularJS当中的数据绑定分为:
1.数据单向绑定:
单向数据绑定是指将模型(Model)数据,按着写好的视图(View)模板生成HTML标签,
然后追加到DOM中显示,如之前所学的artTemplate 模板引擎的工作方式。
绑定的方式有三种:
1. 使用插值语法:{{模型属性}} 加载时,->会造成闪烁。可以使用ng-cloak来避免闪烁
2. 使用ng-bind:ng-bind=“模型属性” ->不会造成闪烁, 只能绑定一个属性
3. 使用ng-bind-template=“{{模型属性}},{{模型属性}}”->可以绑定多值, 不会千万闪烁
2.数据双向绑定:
双向绑定则可以实现模型(Model)数据和视图(View)模板的双向传递.
想要实现视图的数据绑定到模型当中必须得要借助表单才行,在表单当中使用ng-model指令.在input标签当中绑定属性.
<input type="text" ng-model="name">
<hr>
<p>{{name}}</p>
5.作用域
通常AngularJS中应用(App)是由若干个视图(View)组合成而成的,而视图(View)又都是HTML元素,并且HTML元素是可以互相嵌套的,另一方面视图都隶属于某个控制器(Controller),进而控制器之间也必然会产生嵌套关系。
每个控制器(Controller)又都对应一个模型(Model)也就是scope对象,不同层级控制器(Controller)下的scope便产生了作用域。
- 根作用域
一个AngularJS的应用(App)在启动时会自动创建一个根作用域$rootScope,这个根作用域在整个应用范围(ng-app所在标签以内)都是可以被访问到的。- 子作用域
通过ng-controller指令可以创建一个子作用域,新建的作用域可以访问其父作用域的数据。
6.过滤器
在AngularJS中使用过滤器格式化展示数据 ,作用就是接收一个输入,通过某个规则进行处理.然后返回处理结果.
内置9大过滤器:
- currency:将数值格式化为货币格式;
- date:日期格式化,年、月、日、星期、时、分、秒、毫秒,也可以组合到一起使用;
- filter:在给定数组中选择满足条件的一个子集,并返回一个新数组,其条件可以是一个字符串、对象、函数
- json:将Javascrip对象转成JSON字符串。
- limitTo:取出字符串或数组的前(正数)几位或后(负数)几位
- lowercase:将文本转换成小写格式
- uppercase:将文本转换成大写格式
- number:数字格式化,可控制小位位数
- orderBy:对数组进行排序,第2个参数可控制方向
除此之外还可以自定义过滤器,可以满足任何要求的数据处理。
过滤器使用方法:
- 我们可以直接在{{}}中使用filter,跟在表达式后面用 | 分割,语法如下:
{{ expression | filter }} - 也可以多个filter连用,上一个filter的输出将作为下一个filter的输入
{{ expression | filter1 | filter2 | ... }} - filter可以接收参数,参数用 : 进行分割,如下:
{{ expression | filter:argument1:argument2:... }} - 除了对{{}}中的数据进行格式化,我们还可以在指令中使用filter,例如先对数组array进行过滤处理,然后再循环输出:
<span ng-repeat="a in array | filter ">
<body ng-app="app" ng-controller="xmgController">
<p>{{money | currency :"%$^^%%^%$"}}</p>
<hr>
<p>{{money| myCurrency :"%$^^%%^%$" }}</p>
<hr>
<p>{{str | uppercase}}</p>
<hr>
<p>{{str | firstCast}}</p>
var app= angular.module('app',[]);
app.controller('myController',['$scope',function ($scope) {
$scope.money=12;
$scope.str="sabc";
}]);
//自定义过滤器 的关键字是filter
//自定义指令的关键字是directive
app.filter("myCurrency",function () {
//参数1 需要过滤的数据
// 参数2 需要添加的内容
return function (input, args) {
return args+input;
}
});
app.filter("firstCast",function () {
//获得首字母大写
return function (input) {
return input[0].toUpperCase()+input.slice(1);
}
});
7.依赖注入
AngularJS采用模块化的方式组织代码,将一些通用逻辑封装成一个对象或函数,实现最大程度的复用,这导致了使用者和被使用者之间存在依赖关系。
所谓依赖注入是指在运行时自动查找依赖关系,然后将查找到依赖传递给使用者的一种机制。
依赖注入分为两种:
1.行内注入:以数组形式明确声明依赖,数组元素都是包含依赖名称的字符串,数组最后一个元素是依赖注入的目标函数.推荐使用行内式注入.
2.推断注入. 没有明确声明依赖,AngularJS会将函数参数名称当成是依赖的名称
这种方式会带来一个问题,当代码经过压缩后函数的参数被压缩,这样便会造成依赖无法找到。
8.服务
服务是一个对象或函数,对外提供特定的功能。我们要学习的就是这些服务当中给我们提供了哪些功能, 这些功能的作用分别是什么.
常见内置服务有:location、timeout 、filter、log、http 同时还支持多种快捷方式如http.get()、http.post()、http.jsonp。
- $location服务:是对原生JavaScript中的location对象属性和方法的封装.
location服务解析在浏览器地址栏中的URL(基于window.location)并且让URL在你的应用中可用。localtion.ablUrl() 获取绝对路径
localtion.protocol() 获取协议localtion.port() 端口
localtion.path() 当前路径localtion.hash 获取hash值
$localtion.search 查询字符串
查看原生的网络地址
for ( var key in location) {
console.log(key +'=>'+location[key]);
};
var app = angular.module('app',[]);
app.controller('myController',['$scope','$location',function ($scope,$location) {
$scope.absUrl = $location.absUrl();
//获取的是锚点后面的地址
$scope.url = $location.url();
//获取端口号
$scope.port = $location.port();
//获取主机名
$scope.host = $location.host();
//获取的锚点(从第二个锚点开始的值)
$scope.hash = $location.hash();
//获取参数
$scope.search = $location.search();
}]);
<p>{{absUrl}}</p>
<p>{{url}}</p>
<p>{{port}}</p>
<p>{{host}}</p>
<p>{{hash}}</p>
<p>{{search}}</p>
- timeout&interval :timeout&interval对原生Javascript中的setTimeout和setInterval进行了封装。
var app = angular.module('app',[]);
//行内注入
app.controller('myController',['$scope','$timeout','$interval',function ($scope,$timeout,$interval) {
$scope.name = 'pat';
//延时执行任务
$timeout(function () {
$scope.name="Patty121";
},1000);
//隔指定事件执行任务
var timer = $interval(function () {
$scope.dateTime = new Date();
},1000);
//点击按钮时停止定时器
$scope.stop = function () {
alert('aaa');
//停止指定的定时器
$interval.cancel(timer);
}
}]);
<p>{{name}}</p>
<p>{{dateTime | date:'yyyy-MM-dd h:m:s'}}</p>
<button ng-click="stop()">??</button>
- $filter格式化数据:不要在View中过多的处理业务逻辑,应该在控制器当中处理完毕之后,直接显示在view中.
app.controller('myController',
['$scope','$filter',function ($scope,$filter) {
$scope.price = 20;
$scope.str = "hello";
//使用$filter获取9个服务中的一个,获取后再去使用获取的筛选
var currency = $filter('currency');
$scope.price = currency($scope.price);
var uppcase = $filter('uppercase');
$scope.str = uppcase($scope.str);
//可以直接在后面使用
$scope.str = $filter('limitTo')($scope.str,2);
}]);
-
log服务 `log.log()、log.info()、log.warn()、log.errow()、log.debug()`
image.png
-
$http:向服务端发起请求。
<script src="angular.js"></script>
<script>
var app = angular.module('app',[]);
app.controller('myController',['$scope','$http',function ($scope,$http) {
$http({
url: 'get.php', // 请求地址
method:'get', // 请求方式
params:{// get方式传递参数,在传递过程中会自动帮你转成get.php?name =pat,传递时 ->name:pat
name:'pat'
}
}).success(function (res) {
alert(res); //成功时的回调
}).error(function(error){
//失败时的回调
});
$http({
url: 'post.php', //请求地址
method:'post', //请求方式
//post必须设置请求头
headers:{
'Content-Type':'application/x-www-form-urlencoded'
},
//data:{data:{}传参形式在传递数据时,是以json来传递的
name:"pat" // json 串
}
data:'name=pat' formdata
}).success(function (res) {
alert(res);
}).error(function (res) {
});
//当设置请求头的时候为application/x-www-form-urlencoded是以SOAP对象形式传递
SOAP: 以对象形式来进行传递
RESTFUL:json串形式进行传递
}]);
</script>
6.自定义服务:所谓服务是将一些通用性的功能逻辑进行封装方便使用,
AngularJS允许将自定义服务。
自定义服务有三种方式 1.factory 2.service 3.value
- factory方式自定义服务:
通过创建的app的factory进行自定义内置服务在创建自定义服务时, 可以使用内置的服务.
App.factory(‘showTime’,[‘$filter’,function($filer){
var now = new Date();
now = $filter(‘date’)(now,’yyyy/MM/dd’)
return now
}]);
- service方法自定义服务
App.service(‘showTime’,[‘$filter’,function($filer){
var now = new Date();
now = $filter(‘date’)(now,’yyyy/MM/dd’)
return now
}]);
声明依赖调用服务
app.controller(‘MyController’[$scope,’$showTime’,function(){
$scope.now = showTime.now;
}])
- value方法定义常量
App.value(‘author’,’pat’);
App.controller(‘MyController’[‘$scope’,’$author’,function(){
$scope.author = author;
}])
服务本质就是一个对象或函数,所以自定义服务就是要返回一个对象或函数以供使用。
9.配置块运行块
配置块:通过config方法实现对模块的配置,AngularJS中的服务大部分都对应个“provider”,用来执行与对应服务相同的功能或对其进行配置。比如log、http、locatio都是内置服务,相对应的“provider”分别是logProvider、httpProvider、locationPorvider。
运行块:服务也是模块形式存在的对且对外提供特定功能,服务是以依赖注入进去的,然后再进行调用。除了这种方式外我们也可以直接运行相应的服务模块,AngularJS提供了run方法来实现。run方法还是最先执行的,利用这个特点我们可以将一些需要优先执行的功能通过run方法来运行,比如验证用户是否登录,未登录则不允许进行任何其它操作。
AngularJS模块可以在被加载和执行之前对其自身进行配置。我们可以在应用的加载阶段配置不同的逻辑。
10. 路由
SPA:SPA(Single Page Application)指的是通单一页面展示所有功能,通过Ajax动态获取数据然后进行实时渲染,结合CSS3动画模仿原生App交互,然后再进行打包(使用工具把Web应用包一个壳,这个壳本质上是浏览器)变成一个“原生”应用。
通常情况下使用Ajax异步请求数据,然后实现内容局部刷新,局部刷新的本质是动态生成DOM,新生成的DOM元素并没有真实存在于文档中,所以当再次刷新页面时新添加的DOM元素会“丢失”,通过单页面应可以很好的解决这个问题。
特点:实现单页面应用需要具备:a、只有一页面;b、链接使用锚点。
-
使用Ajax实现单页应用程序:
Ajax实现单页面应用 -
angularjs 实现路由的步骤:在angular当中路由就是锚点,用来做单页面应用程序的切换。锚点的变化,我们又称为路由的变化。路由在angular当中属于单独的一个模块,帮你监听锚点的跳转。
1.引入angular-route.js
<script src="angular-route.js"></script>
- 实例化模块时,注入ngRoute模块
var app= angular.module('app',['ngRoute']);
- 配置路由模块
app.config(['$routeProvider',function ($routeProvider) {
//开始配置路由
//只要是监听的锚点变化了,就会执行下面的代码
$routeProvider.when('/home',{
templateUrl:'<h1>首页</h1>'
}).when('/music',{
templateUrl:'<h1>音乐</h1>'
}).when('/contact',{
templateUrl:'<h1>联系我们</h1>'
}).otherwise({
redirectTo:'/home'
});
}]);
- 布局模板
<div class="header">
<ul>
<li><a href="#/home">首页</a></li>
<li><a href="#/music">关于我们</a></li>
<li><a href="#/contact">联系我们</a></li>
</ul>
</div>
<div class="content">
<div ng-view></div>
</div>
补充:
- 路由外链模板
app.config(['$routeProvider',function ($routeProvider) {
//开始配置路由
//只要是监听的锚点变化了,就会执行下面的代码
$routeProvider.when('/home',{
templateUrl:'template/home.html',
controller:'homeController',
}).when('/music',{
templateUrl:'template/music.html',
controller:'musicController',
}).otherwise({
redirectTo:'/home/1'
});
}]);
- 路由传参
//路由配置
app.config(['$routeProvider',function ($routeProvider) {
$routeProvider.when(*'/home/:page'*,{
templateUrl:'template/home.html',
controller:'homeController',
}).when('/music',{
templateUrl:'template/music.html',
controller:'musicController',
}).otherwise({
redirectTo:'/home/1'
});
}]);
//传参
<div class="header">
<ul>
*<li><a href="#/home/1">首页</a></li>*
<li><a href="#/music">音乐</a></li>
<li><a href="#/contact">联系我们</a></li>
</ul>
</div>
<div class="content">
<div ng-view></div>
</div>
网友评论