- Angular是什么?优点?
- 前端MVC框架
- 克服了HTML在构建应用上的诸多不足
- 特点
- jQuery以dom为驱动(核心)
- angularjs以数据和逻辑作为驱动(核心)
- 最核心的是:模块化、双向数据绑定、语义化标签、依赖注入
- MVC是一种开发模式
- M-->model一般用来处理数据(读取/设置),一般用来操作数据库
- V-->view一般用来展示数据,比如通过HTML展示
- C-->controller一般用做连接模型和视图的桥梁
-
thinkPHP:
__PUBLIC__==>得到thinkPHP中的public的路径 assign(title,$title)$title内容分配给title:数据分配 assign(赋值给谁,变量)
- 模块化
-
一旦引入angularJS框架,就会提供一个全局的对象:angular,此对象下有N多方法,其中module方法可以帮我们创建一个模块
var App = angular.module('App',[]);
App就是新创建的模块,这个模块又是一个对象,此对象下又有N多方法,可以实现具体业务逻辑
所以真正实现业务的是App,angular.module()只是构造一个模块
- App.controller('DemoCotroller',['$scope',function($scope){}]);第一个参数是控制器名称
-
使用套路:
要使用ng-app指定联合那个模块,使用ng-controller指定是那个控制器
- 使用方法:
<div class="box" **ng-app='App'**> <div **ng-controller='DemoCotroller'**> <h1>{{name}}在{{school}}学习使用angularjs</h1> </div> </div> <!-- 引入angularJS框架 --> <script src="js/angular.js"></script> <script> **var App = angular.module('App',[]);** **App.controller('DemoCotroller',['$scope',function($scope){ // $scope是一个空的对象,此对象就是model $scope.name = 'zs'; $scope.shool = '微博'; }]);** </script>
-
-
- 指令:
- 内置指令:
- ng-repeat='(key,数组别名) in 数组名' {{数组别名}}可以得到一个个的数组内容 {{key}}可以得到索引
- ng-app:制定应用根元素,至少有一个元素指定此属性
- ng-controller:指定控制器
- ng-show :控制元素是否显示,true显示
- ng-hide:控制元素是否隐藏,true隐藏
- ng-if:控制元素是否存在,true存在、false不存在
- ng-src:增强图片路径
- ng-href:增强地址
- ng-class='{类名:布尔值}':控制类名,true类名有效,false类名无效
- 值可以是字符串,对象或者一个数组,字符串多个用空格分隔,数组可以由字符或对象组成。
- ng-bind:绑定
- ng-include:引入模块,必须放在服务器下面,js本身是读取不了本地文件的
- ....
- 自定义指令:angularjs自定义指令就是HTML属性或者标签,这些指令都是以ng-作为前缀
- 通过模块实例对象的directive()方法可以自定义指令
App.directive('指令名',function(){ return{ restrict:'EM', template:'想要表达的模板', templateUrl:'引入外来模板的路径' } }) <--directive:tag--> 注释 E(Element)表示该指令是一个element; A(Attribute)表示该指令是attribute; C(Class)表示该指令是class; M(Mark replace)表示该指令是注释,必须为true否则出不来
- 通过模块实例对象的directive()方法可以自定义指令
- 内置指令:
- 数据绑定
- 单向绑定:
- 将模型(model)数据绑定到视图(view)上
- 双向绑定:
- 模型向视图、视图向模型
- 单项绑定:
*注意*:ng-bind="表达式" 可以解析 ng-bind-template='字符串' 不可以解析 所以ng-bind后直接是name可以自己去解析,ng-bind-template后面是{{}},{{}}解析后的返回值再作为字符串给ng-bind-template
- {{}}和ng-bind指令来实现模型(model)数据向视图(view)的绑定
- {{}}是ng-bind的另一种写法,优点:更简单 缺点:会有一瞬间的闪动,可以通过添加ng-cloak来解决此问题,原理:添加style样式,设为none等angular编译后在设为block
- ng-bind-template='{{数据一}}{{数据二}}'可以绑定多个数据
- ng-repeat='(key,value) in 数组名':通过迭代将数组或者对象显示到视图上
- ng-switch on、ng-switch-when:组合使用对数据进行筛
- ng-switch on='XXX':对XXX进行筛选
- ng-switch-when='XXX':只有满足XXX是才...
<li ng-repeat='item in items' ng-switch="item"> <span ng-switch-when="css">{{item}}</span> </li>
- 双向绑定:
<body ng-app='App'> <div ng-controller="DemoController"> <input type="text" ng-model="msg"> <button ng-click="show()">显示</button> </div> <script src="js/angular.js"></script> <script> var App = angular.module("App",[]); App.controller("DemoController",["$scope",function($scope){ $scope.show = function(){ alert($scope.msg); } }]); </script> </body>
- 要实现数据从视图向模型传递需要借助于表单元素,在表单元素上面添加一个指令ng-model=' '即:通过为表单元素添加**ng-model**指令实现视图模板向模型数据的绑定
- 单向绑定:
- 作用域:
- js的作用域:
- 新创建一个函数就会产生一个新的作用域,并且子作用域可以访问父级作用域,父级作用域不能访问子级作用域
- angularjs作用域:
- 新创建一个控制器就会产生一个新的作用域,并且子作用域可以访问父级作用域,父级作用域不能访问子级作用域
- 根作用域
- 相当于原始js里面的全局作用域(window),angularjs中ng-app下面的是全局作用域
- js的作用域:
- 过滤器: 格式化展示数据
- 内置过滤器
{{num|number}}默认保留三位小数,可以通过传参来设置保留几位小数
- 使用方式: | 是调用过滤器 : 是传参
- currency:将数值格式华为货币格式
{{price|currency}} {{price|currency:'¥'}}:通过传参的形式改变符号
- date:日期格式化
参数:yyyy-->四位年份 MM-->月份 dd-->日 yyyy-MM-dd hh:mm:ss
- filter:在给定数组中选择满足条件的一个子集,并返回一个新数组,其条件可以是一个字符串、对象、函数
json:{{items|filter:'s'}}:过滤数组中包含‘s’的子集 {{students|filter:{age:18} }}:条件是对象
limitTo:截取字符串、数组{{students|json}}:将数组转换为josn数据
前两个子集{{items|limitTo:2}}:截取字符串前两个字符、截取数组
{{items|limitTo:正数}}:从左边开始截取 {{items|limitTo:负数}}:从右边开始截取
- uppercase:变成大写
-
lowercase:变成小写
number:转换为数字,四舍五入
- orderBy:对数组进行排序,第二个参数可控制方向
{{items|orderBy:'':true}}:进行倒/降序 {{items|orderBy:'':false}}:进行正/升序,默认为false
- 课外:parseInt与number的区别
-
parseInt:从首位查找一直查到不是数字
如:10ad:10 10.12:10 ads10:Nan
-
number:不能有非数字
如:10ad:NaN 12.12:12.12
-
- 自定义过滤器
- 通过filter()来自定义过滤器
- 自定义一个首字母大写的过滤器:capitalize
App.filter('capitalize', function(){ //{{info|capitalize}} 因为使用管道即info的值传递capitalize函数当参数使用,所以需要接收参数,又因为需要把数值展示出来,所以里面的一个函数还需要return来返回值 return function(input){ //这里return function(input):可扩展性强,外面函数调用里面函数返回,否则会出错 return input[0].toUpperCase() + input.slice(1); } });
- 自定义一个首字母大写的过滤器:capitalize
- 通过filter()来自定义过滤器
- 内置过滤器
- 三个自定义
- controller:自定义控制器
- directive:自定义指令
- filter:自定义过滤器
- 依赖注入
- 在使用angularjs进行开发时,需要用angularjs事情先提供的模块,开发自己的业务逻辑例如造一个控制器,需要有一个模块2(模型),这是开发需要小angularjs申请需要的模块2,angularjs会主动去查找有没有一个模块2,找到后再交给开发者,交给的过程成为注入。即告诉angularjs自己依赖于那个模块,angular去找,找到后以注入的方式传递给自己App.controller('DemoController',['$scope',function(参数名称){}]:[]中就是依赖注入,需要$scope模块,angularjs以传参的形式注入给我,参数名称可以随意 可以理解为依赖传参
-
行内式注入:
App.controller('DemoController',['$scope',function(参数名称){}] 可以依赖多个模块,并列写,有几个模块传几个参数,最好参数名称和模块名称相同,防止多个参数混淆
- 推断式依赖注入:App.controller('DemoController',function($scope){});此时参数名称不能乱写,必须要正确,符号也不能省略,因为表示angular内置的意思,是angular自己定义好的
- 现实开发中一般不使用推断式依赖注入,因为代码写完后要进行压缩,参数被压缩后会改变成简单的,最终会因为参数名改变而出错
- 服务:是一个对象或函数,对外提供特定的功能
- 内建服务:
- $location模块是对原生js中的location对象属性和方法的封装,为了获取地址信息
- 从锚点开始往后都是属于url()的信息
- absUrl()获取完整路径 url() host() search()
- hash()锚点:angularjs中的锚点认定是在js认定的锚点中再找#号,有的话才是锚点 protocol()协议 port()端口
- 地址是由若干部分组合成的:
- http:协议 host:www.baidu.com/127.0.0.1:主机 port:端口号 hash:锚点 serch:?name=itcase&age=10:查询参数数据
- $filter模块:
- $filter():代表了所有的过滤器,可以通过传参数的方式来使用过滤器
$scope.str = 'hello angular'; var uppercase = $filter('uppercase'); $scope.str = uppercase($scope.str); 合并写为:$scope.str1 = 'hello javascript'; $scope.str1 = $filter('uppercase')($scope.str1);
- $filter():代表了所有的过滤器,可以通过传参数的方式来使用过滤器
- $log模块:日志服务 $log.info() warn() error() log() debug()
- $http模块:ajax params{}里面的内容会自动拼接在url后面
- $location模块是对原生js中的location对象属性和方法的封装,为了获取地址信息
- 自定义服务:依赖于$filter, 提供了三种方法实现自定义服务:factory、service、value
- factory:
App.factory('format', ['filter', function(filter){return function (arg){};}]);
- srvice:
this.函数名 = function(){} === return {函数名:function(){}} var App = angular.module('App', []); App.controller('DemoController', ['scope','showTime', function(scope,showTime){ $scope.now = showTime.now(); }]); | | 服务名 函数名 App.service('showTime',['filter',function(filter){ var now = new Date; var date = $filter('date'); this.now = function(){ return date(now,'yyyy-MM-dd hh:mm:ss'); } }]);
- value:功能单一 本质上是一个服务,但是表现形式上看,更像一个系统常量
App.controller('DemoController', ['scope','author','version', function(scope,author,version){ $scope.author = author; $scope.version = version; }]); App.value('author', '朱一龙'); App.value('version', '1.0');
- ajax补充:XMLHttpRequest对象,具备向服务端发送请求和接收响应的一个能力
var xhr = new XMLHttpRequest; xhr.open('get/post','url'); post请求时,由于数据是放到请求主体里的,所以必须要设置请求头(xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');)。get请求的时候没有请求主体,所以不用设置,即send()/send(null)。 请求主体就是请求的数据 xhr.send(); xhr.onreadystatechange = function(){}
- factory:
- 内建服务:
- 跨域限制:
- 标签的src和href属性没有跨域限制
- ajax的$http:
$http({ url:'请求地址', type:'请求方式', data:'传递的参数 name=itcase&age=10', success:function(data){data返回的数据} });
- angular的$http:
params{}里面的内容会自动拼接在url后面 $http({ url:'请求地址', method:'请求方式 jsonp', headers:{请求头}, data:{post传递的数据}, params:{get请求的数据 call:'JSON_CALLBACK}--->回调函数,固定死的 }).success(function(返回的数据){});
- 模块加载:在代码中,一个服务就是一个模块
App.config(['filterProvider',function(filterProvider) { $filterProvider.register('capitalize',function(){ return function(input) { return input[0].toUpperCase() + input.slice(1); } });
- 配置块:通过config来配置服务,angular中服务大部分都对应一个“provider”,用来执行与对应服务相同的功能或对其进行配置。如$log对应的是$logProvider....新增一个过滤器:
- 运行块:直接运行$http、$rootScope服务
App.run(['http','rootScope', function(http,rootScope){ $http({ url:'example.php', method:'get', }).success(function(info){ console.log(info); }); $rootScope.name = '朱一龙'; //如果在controller中又定义了name则会覆盖这个 }]);
- 路由
- SPA:单页面应用,若干个功能集中到一个页面,不产生跳转。动态产生数据,通过ajax异步获取。 增强了用户体验,可以提高性能
- 锚点是前端的路由功能
- hashchange事件可以监听锚点变化
window.addEventListener('hashchange',function(){var hash = location.hash;//获取锚点 ...} $routeProvider.when('/index',{template: '<h1>Index Page!</h1>'}) 第一个参数是条件,第二个参数是一个对象,配置当前路由的参数、如视图、控制等 template:字符串形式的视图模板 templateUrl:引入外部视图模板 controller:视图模板所属于的控制器 redirectTo:跳转到其他路由
- 路由参数:
- $routeParams服务传递参数 == ?号传参
- 通过传参的方式:
href="#/index/5" target="_blank" rel="external nofollow" -->实参 when('/index/:形参名')
- 转换:
- angular.element() 方法可以讲一个原生DOM对象转成jQuery对象
- 但是angularJS只能实现jQuery对象的部分方法 ,即angular‘s jqLite
- 如果页面中引入了jQuery文件,那么不能实现的一部分也能实现了,即全部功能都实现
- $()将原生dom随想转化为jQuery对象
- angular.element() 方法可以讲一个原生DOM对象转成jQuery对象
- bower:用来管理静态资源的工具 即用来下载插件的
- 使用nodejs开发的,要想使用bower,需要先安装nodejs,nodejs就是一个软件,正常安装即可(下一步下一步)。
- 在git窗口中:
- bower install 想要下载的文件名称
- bower info 文件名称 查看信息
- bower uninstall 文件名称 卸载
- bower search 关键字 查找信息
- 可以自动解决依赖:如果再安装一个文件A,此文件A有依赖前提时,bower会自动将所依赖的文件B也给下载下来,且卸载的时候只能卸载文件A不能直接卸载文件B
- 使用angularjs写项目:(可忽略)
- 目录结构: 为了方便管理,统一建立模块、过滤器、指令来管理下面的模块...
- PHP中strtotime()函数可以回到过去的时间。$today = strtotime('-1day', time());-->回到当前时间的前一天
- 大写M:表示月份的三个缩写字母,小写m表示月份的数字带前导0....
- Gulp
- 本地(项目)安装gulp
- 项目构建,构建任务清单gulpfile.js文件
- gulp插件:在gulpfile.js文件书写下列内容:
所有插件是用的前提都是要先使用require('插件名');命令引入进来,引入后都是函数 -npm install gulp-less 将less文件转成css文件 使用方法:首先引入本地安装的gulp与gulp-less 然后:gulp.task('test',function(){ return gulp.src('./public/less/.less')// 借助gulp.src来制定less的文件位置,通俗地讲就是‘去哪拿’ 当想要拿到文件夹中的文件夹里的内容是可以使用两个 // 借助gulp插件实现less转css的操作 .pipe(less()) .pipe(cssmin()) .pipe(gulp.dest('./release/public'));// 通过gulp.dest进行存储 }); 最后:gulp zr执行 return:为了保证同步执行
- Gulp插件:
- npm install gulp-cssmin 将css文件压缩
- npm install gulp-imagemin 图片压缩
- npm install gulp-uglify 压缩JavaScript
- npm install gulp-concat 合并(js的任务,可以先合并后压缩,由于多个文件合并为一个文件所以需要重新取名字:.pipe(concat('all.js')).pipe(uglify())... ) 只合并,路径不改
- npm install htmlmin 压缩HTML文件
.pipe(htmlmin{collapseWhitespace: true})合并空白处 gulp.src(['./index.html','./views/*.html'],{base:'./'}).pipe(dulp.dest('./release'))-->代表着./不动,index.html直接放到./release下面,而后面一个是放到./releaseviews/下面
- npm install gulp-autoprefixer 添加css私有前缀
- npm install gulp-rname 重命名
- npm install gulp-rev 添加版本号
.pipe(rev()).pipe(gulp.dest('...')).pipe(rev.manifest()).pipe(gulp.dest('...'))-->添加版本号(即改为加密的名字)后需要先存好然后再通过rev.manifest()方法找rev()方法操作的文件,将对应关系收集(记录把原始名字改成的新名字)起来放到另一个存储地
- npm install gulp-rev-collector 内容替换
gulp.src(['替换内容','被替换内容']).pipe().pipe(gulp.dest()) 替换内容是rev.manifest()收集的新旧名称对应关系,将被替换内容里面的旧名称换成新的
- npm install gulp-useref 合并文件不压缩 路径改变
合并的文件需要使用注释标记一下:<!-- bulid:xxx ./main.yyy(路径)--><!-- endbulid --> ./main.yyy--:更改的路径文件 pipe(useref()).pipe(gulpif('*.js', uglify() )) -->如果是js文件就丑化压缩一下 gulp-useref:也支持删除 <!--bulid:remove--<!--endbulid-->
- npm install gulp-if
- 总结:由于项目都是按文件夹分好类的,所以可以单纯的认为一个文件夹可以定义一个任务gulp.src([])中可以放数组已达到能够写多个不同地址的文件
- npm init 创建package.json文件记录我们的配置信息
- --svae-dev 与 --save的区别:
--save 会把依赖包名称添加到 package.json 文件 dependencies 键下, --save-dev 则添加到 package.json 文件 devDependencies 键下 会在package.json记录依赖关系 据npm文档所说dependencies是运行时依赖,即dependencies 下的模块,是我们发布后还需要依赖的模块,如jQuery库或者Angular框架类似的,我们在开发完后后肯定还要依赖它们,否则就运行不了。 devDependencies是开发时的依赖,即devDependencies 下列出的模块,是我们开发时用的, 比如 我们安装 js的压缩包gulp-uglify 时,我们采用的是 “npm install –save-dev gulp-uglify ”命令安装,因为我们在发布后用不到它,而只是在我们开发才用到它。
- 一次性运行:
最后可以在定义一个任务来依赖其他的任务已达到一次性执行:gulp.task('all',['zr','image','...'],function(){console.log('全部完成!')}); 或gulp.task('all',['zr','image','...']);