webstrom使用:
ctrl+b/点击,代码导航,自动跳转到定义
ctrl+n跳转指定类
ctrl+d复制当前行ctrl+enter另起一行ctrl+y删除当前行
ctrl+alt/shift+b跳转方法实现/定义处
包裹/去掉外围代码unwrap...
主题appearance
字体editor-colors&fonts-font
自动换行settings-editor-appearance-show line
显示行号..........................show line numbers
代码对齐..........................show right margin
代码提示速度...editor-code completion,autopopup in(ms):0
代码拼写检查设置
ctrl+e打开最近文件
代码补全settings-javascript-libraries-down/xxx.ts定义文件定位
git配置:editor-github改github账户
插件安装file-plugins css-X-fire插件:firebug修改css属性时,编辑器内的css代码也会发生变化
禁用部分插件提高打开速度
webstrom配置nodejs:
settings-->languages....-->nodejs....-->选择文件exe;配置source code:directory;c:\.....\npm
Node.js:
js运行在浏览器/客户端的语言,主要对象包括ES原生对象(11个)、BOM对象、DOM对象
node.js运行于服务器端,类似于php,jsp,asp.net;主要对象包括:es对象、1000+扩展对象;可以编写独立的服务器应用/向web发送数据;基于服务器和客户端的v8引擎,访问服务器端文件系统/数据库
node.js与php+Nginx性能对比:node.js每秒响应请求数较多(输出/执行mysql查询)
LTS: Long Term Support 下载:https://nodejs.org
npm全局模块存放路径;cache缓存路径
,一个
Node.js 文件就是一个模块,这个文件可能是 JavaScript 代码、JSON 或者编译过的 C/C++ 扩展。
Node.js 特点:异步式 I/O(或者非阻塞 I/O)与事件紧密结合的编程模式;
控制流很大程度上要靠事件和回调函数来组织
①node两种运行模式:
交互模式:REPL模式,cmd:node
脚本模式:node xxx.js绝对路径或cmd:e:-->cd 文件夹-->node 文件名
node -v查看版本
②调试:命令行调试:cmd:node debug debug.js,
单击行号添加断点
③nodejs HTTP模块:内部是用 C++ 实现的,外部用 JavaScript 封装
HTTP协议的内容:nodejs需手动设置http协议,php通常不需要设置http协议
(1)请求消息
GET /web/index_new.html?tedu HTTP/1.1
Host: tmooc.cn
Connection: keep-alive
(2)响应消息
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=UTF-8
QueryString模块:用于解析键值对形式的查询字符串,得到一个对象。
HTTP 协议规定,请求消息可以在URL后面追加一个?开头的QueryString,用于向服务器提交请求数据。
var qs=require("querystring"); //引入指定模块
var str = 'uname=tom&upwd=123&age=20';
var obj=qs.parse(str); //将str解析为对象
URL模块:解析一个完整的URL地址,得到其中的各个部分
var url=require("url");
var str="http://tedu.cn:80/s.do?k1=v1&k2=v2";
var obj=url.parse(str,true); //true表示使用
手动解析?后内容,获得表单数据,get请求在url上返回数据
FileSystem模块:用于操作文件系统,读写目录、读写文件,Node.js底层使用C程序来实现
var fs = require('fs');
var data = fs.readFileSync('源文件名',['utf-8'],[f(err,data)]); //同步读取文件内容到缓冲区
fs.readFile(file,['utf-8'],[f(err,data)]) //异步读取文件
fs.writeFileSync('目标文件名', '要写出的内容'); //向文件中写出内容
fs.appendFileSync('目标文件名', '要追加的内容'); //向文件中追加内容
④nodejs第三方模块:https://www.npmjs.com/全世界最大的node.js第三方模块集散地
第三方模块js必须保存在js同级目录下的名为node_modules的文件夹中
MySQL模块:npm
var mysql=require("mysql");
var coon=mysql.createConnection({
host : '127.0.0.1',
user : 'root',
password : '',
database : 'tedu'
});
conn.query('INSERT/SELECT...',f(err,result){});
conn.end();
⑤创建一个静态Web服务器:
步骤:
创建一个HTTP Server
为server指定处理请求消息的过程(获取请求数据,返回响应数据,http、url、fs模块)
解析请求URL中的资源名称, 如 /login.html
读取指定文件中的内容,如 htdocs/login.html
构建响应消息,把读取到的文件内容输出客户端客户端
让server开始监听特定端口
var http = require('http');
var server = new http.Server();
server.on(事件, f(){ //解析url,读取html文件 });
server.listen(端口号);
事件:
request:f返回http.ServerRequest请求对象,http.ServerResponse响应对象参数
req请求对象:
req.url:请求文件的url,作为url字符串使用
req.data(chunk):请求体数据到来时被触发,chunk请求体数据,
全部数据:datas+=chunk;该事件会多次调用
用于表单的post请求,post请求在请求体中返回数据
req.end():请求体数据传输完成触发
req.close():请求结束触发,包括用户强制终止传输
res响应对象:输出到客户端
res.writeHead(status,[headers]):向客户端发送请求头,status状态码
res.write(data,[encoding]):发送响应内容,data内容,encoding编码方式
res.end([data],[encoding]):结束相应,不调用则客户端永远处于等待状态
connection:TCP连接建立被触发
close:服务器关闭时触发,不包括用户连接断开
修改代码后必须终止Node.js 再重新运行才会奏效(不能刷新)
ex:启动服务器并开始监听3000端口:
var http = require('http');
var server=http.createServer(function(req, res) { //http.createServer()创建http.Server服务器对象
res.writeHead(200, {'Content-Type': 'text/html'}); //请求成功的响应代码200
res.write('<h1>Node.js</h1>'); //返回响应体
res.end('<p>Hello World</p>');
}).listen(3000); //链式,
console.log("HTTP server is listening at port 3000.");//进程一直等待,直到按下ctrl+c退出
打开浏览器访问 http://176.2.18.39:3000
⑥创建一个动态Web服务器:
解析url资源:xxx.html或xxx.do
为Server指定处理请求消息的过程
若请求资源名称以.html结尾,直接读取指定文件中的内容,如 htdocs/login.html,作为响应消息数据;
若请求资源为xxx.do,解析请求数据,访问数据库,把执行结果作为相应消息数据
构建响应消息,把读取到的文件内容输出客户端客户端
让Server开始监听特定端口
⑦共享80端口:虚拟主机,就是让多个网站共享使用同一服务器同一IP地址,通过域名的不同来划分请
求;在Nginx 中设置反向代理和虚拟主机非常简单,下面是配置文件的一个示例:
server {
listen 80;
server_name mysite.com;
location / {
proxy_pass http://localhost:3000;
}
}
这个配置文件的功能是监听访问mysite.com 80 端口的请求,并将所有的请求转发给
http://localhost:3000,即我们的Node.js 服务器。现在访问http://mysite.com/,就相当于服务器
访问http://localhost:3000了。
在添加了虚拟主机以后,还可以在Nginx配置文件中添加访问静态文件的规则(具体请
参考Nginx文档),删去app.js 中的app.use(express.static(__dirname + '/public'));。
这样可以直接让Nginx 来处理静态文件,减少反向代理以及Node.js 的开销。
MVC架构:设计模式之一,
Model:模型,项目中的数据;
View:视图,数据的呈现;
Controller:控制器,获取模型数据,选择视图加以呈现
模板为中心的架构:PHP、ASP、JSP
AngularJS:js框架
致力于开发单页面应用程序(Single Page Application)
易于构建页面CRUB操作
一切操作都以数据为中心:创建/绑定/修改/更新数据;基本思路与jQuery的先查找元素再操作元素不同
AngularJS四大特性:采用MVC模型,双向数据绑定,依赖注入(DI),模块化设计
使用:
引入js文件:angular.js;<script src="js/angular.js"></scropt>
为父级元素声明ng-app属性;
在父级元素内部使用AngularJS:<p>{{1+2}}</p>
AngularJS的MVC:
ng-controller声明模型数据:
<html ng-app="myapp"> //定义模块名并确定模块作用范围
<div ng-controller="myctrl"> //控制器组件
<p>{{num}}</p> //绑定数据
</div>
<button ng-click="add($index)">loadMore</button> //传入参数
</html>
var app = angular.module('myapp',[]); //声明模块
//一个模块可以定义多个功能组件:controller,directive,filter,service,...
app.controller("myctrl",function($scope){ //声明控制器
console.log($scope);
$scope.num=10; //定义模型数据,存在$scope对象中
$scope.add=function(){...} //定义模型函数
})
或angular.module('模块名',[依赖列表]).controller("控制器",function($s){s.xxx;});
双向数据绑定:
Model数据绑定到View:脏数据检查(Dirty Checking):model数据的修改自动更新到View
①{{表达式}}:
+ - * / % > >= == === !== && || ! ?: {{20>18?1:0}}
不允许:1++,1--;1+=2;
特殊运算符:typeof(num),age instanceof String;
new和var关键字
{{{'ename':'tom'}.ename}}获取对象的成员属性 member={ename:'tom'}
{{member.ename}}
{{'hello'.toUpperCase()}}获取对象的成员方法
{{['tom','mary'][1]}}获取数组中的指定元素
②指令directive:标签内添加属性,封装DOM操作
ng-app[="模块名"] 初始化一个AngularJS应用程序,确定一个应用模块的作用范围;
ng-init="表达式" 声明/赋值变量,不推荐,变量可赋值值/数字/对象{},双向绑定
x1=val;x2=val; car={name:'BMW',price:'30'}
ng-bind="表达式" 表达式的值输出为当前元素的innerHTML;将模型变量绑定到视图中
{{...}}去输出表达式结果时,有可能会出现闪烁,ng-bind代替输出防止闪烁
ng-repeat="v in arr/obj" 循环生成当前元素,为HTML增加循环功能
<li ng-repeat="tmp in arr/obj">{{tmp}}</li> tmp下标,常用{{arr.tmp/tmp.xxx}}
ng-repeat="dish in list track by $index"
ng-repeat="(k,v) in arr/obj"
<li ng-repeat="(k,v) in car">{{k}} {{v}}</li> arr:k下标;obj:循环输出键值对key,value
ng-if="表达式" 表达式为true,当前元素会挂到DOM,否则删除
<tr ng-repeat="tmp in stuList" ng-if="tmp.chinese > 60">{{tmp}}</tr>满足ng-if时循环输出tmp
ng-include="'tpl/footer.html'" 替换某标签内片段,如footer
ng-controller="控制器" 每个控制器有一个$scope作用域对象,可嵌套
控制器应该尽可能保持短小精悍,而在控制器中进行DOM操作和数据操作则是一个不好的实践。
<ANY ng-xx=''/> xx:html标签的扩展属性
ng-click="f()"
ng-src="img/{{url}}" <img ng-src="img/{{dish.url}}" alt=""/>
err-src="img/404.jpg" 若图片加载失败,404报错时,提供备用图片
ng-herf=“...”
<ngView />扩展标签
ng-show/hide="isshow" ngShow表达式计算结果为假时,ng-hide CSS 类会被加到元素的class属性中
<p ng-show='hasMore' ng-click="add()">添加更多按钮</p>
<p ng-hide="hasMore">没有更多数据可以加载了</p>
ng-style/class
ng-checked
ng-disabled
ng-model=”val” 绑定input,select,texttarea;¥scope.val=...;
View数据绑定到Model:View数据的修改自动更新到Model
①ng-model="模型变量名" 只有表单控件的值可以修改:input,多行文本textarea,下拉框select,单选复选
<input type="checkbox" ng-model="isAgree">
<button ng-disabled="!isAgree">111</button>
$scope.$watch('agree',function(){console.log($scope.agree);}) 使用$scope.$watch()监视到模型数据的每次修改
过滤器filter:对表达结果进行筛选/格式化;| 管道,用于数据传递
{{ 表达式 | filter[:params] | filter2[:params] }}
number:小数部分有效位数 格式化数字,若不是数字则返回空字符串
currency:'货币符号' 格式化为货币形式$
{{sum()|currency:'¥'}} sum():return value;
date:'日期时间格式' 把date/string/number转换为特定的日期格式
{{nowDate | date:'yy-MM-dd'}} $scope.nowDate = new Date();
upperCase 所有字符转换为大写
lowerCase 小写
orderBy:表达式 对数组进行排序,默认增序,true降序,
<li ng-repeat="tmp in friends|orderBy:'age'[:true | limitTo:3]>{{tmp.name}} {{tmp.age}}</li>只显示前三名
limitTo:n 返回指定长度
函数function:
angular.uppercase(string); 大写转换
angular.lowercase(string); 小写
angular.fromJson(jsonStr); 反序列化
angular.toJson(obj, [pretty]); 序列化,json->str
angular.forEach(obj/arr, fn(value,key), [context]); 对obj/arr的每个条目调用一次fn
angular.module(name, [requires], [configFn]); 创建模块,angular.module('app',['ng'/依赖列表])
服务service:每个service对象都是单例的
常用内置服务/注入对象:
$scope: 作用域对象,子$scope若找不到值则访问父$scope,直到$rootScope中也找不到
$scope.$watch("模型变量名",function(to,from){....},[false/true]); 监听模型数据变化,
每次进行model到view的绑定都会创建一个$watch追加到$watch队列中
$scope.$digest() 手工触发$watch队列中的所有监听函数,
$scope.$apply(function(){...}) 对$scope.$digest()的进一步封装,建议使用$apply方法完成$digest的调用
angular上下文环境中对模型修改自动调用;若在上下文环境之外被修改需手工调用
$scope.$apply();<==> $rootScope.$digest();
$location:
controller(控制器名,function($scope,$location){ //使用某个服务则需在控制器的回调函数中注入进来
console.log($location.absUrl()); //获取地址
});
$http:可以向服务器发起ajax请求,异步的获取服务器端返回的相应数据,默认json数据
$http({method:"GET/POST",url:"/url"}) 请求地址:data/test.json或php
.success(function(data, status, headers, config){})
.error(function(data, status, headers, config){});
$http.get("/url").success(fn(data,...)); 传数据url+?k=v
$http.post("/url",data).success(fn);
$http.head
$http.put
$http.delete
$http.jsonp
$rootScope 根作用域对象,所用的控制器实例共用,用于跨控制器共享模型数据
module.controller('控制器名',function($rootScope){$rootScope.模型变量=值;$rootScope.模型方法=fn;})
$window:提供对于浏览器的 window 对象的包装引用。
$animate:实现动画
$log
$interval:周期性定时器
$scope.timer=$interval(function(){
})
终止定时器$interval.cancel($scope.timer);
<==>setInterval($scope.f(),1000)
$timeout:一次性定时器
$timeout(function(){...},1000);
<==>setTimeout(fn,time)
依赖注入(Dependency Injection):$injector注入器快速定位到需要注入的各种服务
①推断式依赖注入:不需要关注注入时参数的先后顺序,ng会根据参数查找对应的服务并注入进来,这种方式不能处理压缩或者混淆后的代码,只能处理原始的代码
自定义服务
app.factory('服务名字',function(){
return {
方法名:function(){},
属性名:属性值
};
});
app.controller('MyCtrl',function($scope,$show){$service.方法()/属性}
②标记式依赖注入:直接调用$inject属性来完成(字符型数组)
var ctrFunc = function ($scope,$print,$show) {
$scope.callShow = function () {
$show.show();
}
$scope.callPrint = function () {
$print.print();
}
};
ctrFunc.$inject = ["$scope","$print","$show"];
app.controller('myCtrl',ctrFunc);
③行内式依赖注入:允许我们将一个字符数组作为对象的参数;在这个数组中,除最后一个元素必须是函数体之外,其余都是注入的服务名称。
app.controller('MyCtrl',["$scope","$show",function($scope,$show){...}])
得到注入器:auto/service
var injector = angular.injector(['myApp','ng']);
或app.controller('myCtrl',fn($scope){
$scope.f=function(){
var injector=angular.injector(['myApp','ng']); //通过注入$injector服务代替angular.injector()
injector.has('$show')...
}
}
injectorAPI:
injector.has('$show'):从注册列表中查找对应服务,找到返回true
injector.get('$show'):返回指定名称的服务实例,获取实例之后,调用服务中的属性和方法
压缩文件:
YUICompressor:雅虎UI库,java语言编写,压缩css/js文件
删除所有注释,无语义的空白字符,将变量名/函数名替换为尽可能短的形式
安装java运行环境-jdk
通过命令行:java.exe -jar C:\yui-compressor.jar C:\demo03Js.js > C:\demo.min.js
或webstorm配置yuicompressor,监视并自动进行压缩
file-settings-file watchers-+添加yui-配置jar包路径
压缩文件的依赖注入:
压缩过程会对函数的形参名进行精简压缩,则Angular无法识别,从而无法实现注入
解决:行内式依赖注入:module.controller('控制器名',['$scope','$http','$log',function($scope,$http,$log){...}])
模块化:
b模块使用a模块当中的东西,在b模块声明的时候,在依赖列表中写上对应的模块名字
var app01=angular.module("myApp01",[]);
var app02=angular.module("myApp",['ng','myApp01']);
面试题:一个ng模块,可以包含哪些组件:
①controller:多个控制器组件
②directive:指令,view中绑定模型数据
③service:服务,在不同控制器之间提供某种函数服务
④filter:过滤,筛选,格式化输出
⑤function:
provider组件:类似于service,较少使用
type组件:比如
object组件:有些对象,很少用
自定义指令
app.directive('指令名'.function(){ //驼峰式命名tsHello,使用则ts-hello
return{
restrict:'EAC', //限制值:E(Element)A(Attribute)C(Class)M(Comment)
template:'该指令实际对应的HTML内容', //替换标签内文本
templateUrl:'xxx.html'
};
})
普通标签使用:<ts-hello></ts-hello>
属性使用:<p ts-hello></p>
class使用:<p class="ts-hello"></p>
创建一个服务:
app.service('服务名',function(){ //服务名:$xxx
this.xx=xxx;
this.yy=function(){...}
})
factory是普通方法,service是构造函数
自定义过滤器:
app.filter('过滤器名',function(){
return function(输入参数){
//处理过程
return 处理结果
}
})
SPA(single page application)单页应用工作原理:
1.url形式:http://127.0.0.1/index.html#/路由地址
2.浏览器先拿到index.html,再解析路由地址
3.路由词典
#/start==>tpl/start.html
#/main
4.获取到真实页面地址,发起请求,获取末班页面,插入到DOM树,实现刷新
路由模块:
①创建一个完整html页面,引入angular.js和angular-route.js
②声明模块angular.module('myApp',['ng','ngRoute']);
③html中使用ngView声明一个容器元素,盛放代码片段
④创建模板页面
⑤配置路由词典
app.config(function($routeProvider){
$routeProvider.
when('/路由地址1',{ //页面url:/start
templateUrl:'模板页面地址1', //文档url:xxx.html,包含片段如<p>..</p>,无需完整结构
controller:"starCtrl" //声明控制器
}).when('/路由地址2/:index',{ //:index变量前加冒号
templateUrl:'模板页面地址2',
controller:"mainCtrl"
}).otherwise({
redirectTo:'/路由地址1' //默认其他跳转url
})
});
模板跳转:
超链接:<a href="#/路由地址">...</a>
js实现:
<button ng-click="jump()"></button>
$scope.jump=function(){ $location.path("/路由地址"); }
var app = angular.module('myApp',['ng','ngRoute']);
app.controller('startCtrl',
['$scope','$location',
function ($scope,$location) {
$scope.jump = function () {
$location.path('/login');
}
}]);
读取路由参数:
.controller("...",function($routeParams){console.log($routeParams.dno);})
动画模块ngAnimate
依赖两种技术:
CSS Transition/Keyframes动画
声明ngAnimate依赖模块后,元素消失/显现时自动添加的class
.ng-enter:元素消失=>存在时,刚一进入时的状态
.ng-enter-active:元素消失=>存在时,进入完成时的状态
.ng-leave:存在=>消失时,刚一离开时的状态
.ng-leave-active:存在=>消失时,离开完成时的状态
中间的动画的执行由css transition实现
通过设置四个class来添加动画
.page {
position: absolute;
width: 100%;
}
.page.ng-enter,
.page.ng-leave {
-webkit-transition: .5s linear all;
-moz-transition: .5s linear all;
-ms-transition: .5s linear all;
-o-transition: .5s linear all;
transition: .5s linear all;
}
.page.ng-leave {
left: 0;
opacity: 1;
}
.page.ng-leave.ng-leave-active {
left: -100%;
opacity: 0;
}
.page.ng-enter {
left: 100%;
opacity: 0;
}
.page.ng-enter.ng-enter-active {
left: 0;
opacity: 1;
}
jQuery.animate()函数
引入jquery.js,angular.js,angular-animate.js
创建模块,声明对ngAnmiate模块的依赖
var app = angular.module('kaifanla',['ng','ngRoute','ngAnimate']);
app.animation(‘要使用动画的元素选择器’,function(){
return{
enter:function(e,fn){
$(e).css({刚一进入时的初始状态});
$(e).animate({刚入完成时的状态},2000,fn);
},
leave:function(e,fn){
$(e).css({刚一离开时的初始状态});
$(e).animate({离开完成时的状态},2000,fn);
}
}
})