whitejy / learn Goto Github PK
View Code? Open in Web Editor NEW学习使用
学习使用
1、 全局变量
node提供了两个全局变量
__dirname: 指向当前运行脚本所在的目录;
__filename:指向当前运行脚本的文件名;
2、回调函数
回调函数本身的第一个参数为上一步传入的错误对象
function callback(error,value){
if(error){
}
xxxx
}
第一个参数不传则为null。
fs.readFileSync(src);
fs.writeFileSync(dist, src);
大文件读写:
fs.createReadStream(src).pipe(fs.createWriteStream(dist));
路由:
1、路由的path匹配,按照先后顺序来匹配,确定的path放在最前面,通用匹配符放在最后面。
2、路由重定向必须增加pathMatch,包含两个值:full和prefix,full是全词匹配,prefix是前缀匹配。
3、路由模块需要将RouterModule在exports中导出。
4、在根模块下调用 RouterModule.forRoot,在其他模块下就只能调用RouterModule.forChild;
5、导入模块的顺序很重要
imports: [
BrowserModule,
FormsModule,
HeroesModule,
AppRoutingModule
],
路由配置的顺序很重要。 路由器会接受第一个匹配上导航所要求的路径的那个路由。
当所有路由都在同一个 AppRoutingModule 时,你要把默认路由和通配符路由放在最后(这里是在 /heroes 路由后面), 这样路由器才有机会匹配到 /heroes 路由,否则它就会先遇到并匹配上该通配符路由,并导航到“页面未找到”路由。
1、 string类型通过 + 连接的话,不能直接连接两个已知的字符串,必须存在变量。
如: string a = "hello" + "world"; //错误
string s= "hello"; string a = s + “world”; //正确
2、 初始化
可以直接使用 = 初始化,也可以使用 () ,比如:string a("hello");
3、+ 连接符
+号连接符是连接两个string类型的数值的,如果有一个不是string,那么使用 + 连接的话就不能展示。
如: cout << "my age is :" + age << endl; //age为int类型,不能输出,要输出的话,只能使用 << 流,即:cout << "my age is :" << age << endl;
var f = v => v;
上面的箭头函数等同于:
var f = function(v) {
return v;
};
如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。
var f = () => 5;
// 等同于
var f = function () { return 5 };
var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
return num1 + num2;
};
如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。
var sum = (num1, num2) => { return num1 + num2; }
由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号。
var getTempItem = id => ({ id: id, name: "Temp" });
箭头函数可以与变量解构结合使用。
const full = ({ first, last }) => first + ' ' + last;
// 等同于
function full(person) {
return person.first + ' ' + person.last;
}
1、setTimeout & setInterval
对于延时函数内部的回调函数的this指向全局对象window(当然我们可以通过bind方法改变其内部函数的this指向)
function Person() {
this.age = 0;
setTimeout(function() {
console.log(this);
}, 3000);
}
var p = new Person();//3秒后返回 window 对象
2、箭头函数的this
var adder = {
base : 1,
add : function(a) {
var f = v => v + this.base;
return f(a);
},
addThruCall: function inFun(a) {
var f = v => v + this.base;
var b = {
base : 2
};
return f.call(b, a);
}
};
console.log(adder.add(1)); // 输出 2
console.log(adder.addThruCall(1)); // 仍然输出 2(而不是3,其内部的this并没有因为call() 而改变,其this值仍然为函数inFun的this值,指向对象adder
作为方法的箭头函数this指向全局window对象,而普通函数则指向调用它的对象
var obj = {
i: 10,
b: () => console.log(this.i, this),
c: function() {
console.log( this.i, this)
}
}
obj.b(); // undefined window{...}
obj.c(); // 10 Object {...}
总结:箭头函数中的this是指向父级的执行上下文。
即上面的例子,父级为obj对象,而obj对象的执行上下文为windows对象
参考:https://www.cnblogs.com/dongcanliang/p/7054176.html
https://blog.csdn.net/liwusen/article/details/70257837
sessionStorage 、localStorage 和 cookie 之间的区别:
共同点:都是保存在浏览器端,且都遵循同源策略。
不同点:在于生命周期与作用域的不同
作用域:localStorage只要在相同的协议、相同的主机名、相同的端口下,就能读取/修改到同一份localStorage数据。sessionStorage比localStorage更严苛一点,除了协议、主机名、端口外,还要求在同一窗口(也就是浏览器的标签页)下。
生命周期:localStorage 是持久化的本地存储,存储在其中的数据是永远不会过期的,使其消失的唯一办法是手动删除;而 sessionStorage 是临时性的本地存储,它是会话级别的存储,当会话结束(页面被关闭)时,存储内容也随之被释放。
服务器产生一个sessionid,每次页面提交的时候,浏览器将这个sessionid携带在http头部提交到服务器端。
其实客户端Session默认是以cookie的形式来存储的,所以当用户禁用了cookie的话,服务器端就得不到SessionID
1.管道
我们的很多应用场景是基于这样一个简单的任务,获取数据,转换过滤后再展示给用户,angular2中我们引入了管道(Pipes)的概念,即管道是用来将数据模型中的数据经过过滤转换,然后通过模板内并展示给用户,这样做是为了更好的用户体验,例如从视图模型中直接获得的数据,不一定完全是我们想要的格式或者适合于人们查看的,举个例子,我们需要获取一个班级所有学生的平均分:
1.1 管道的用法
在angular2中,管道是在模板中对输入数据进行变换,并输出变换后的结果。在模板的内嵌表达式中,使用管道操作符“|”和其右边的管道方法来实现一个管道操作,使用“:”来向管道传入参数,所有的管道都是沿用这样这的一种机制。我们举个简单的例子来说明一下管道的使用:
import {Component} from 'angular2/core'
@component({
selector: 'hero-birthday',
template: <p>The hero's birthday is {{ birthday | date:"MM/dd/yy" }}</p>
})
export class HeroBirthday {
birthday = new Date(1988,3,15); // April 15, 1988
}
我们通过视图组件获取到我们要输出的生日日期birthday,通过插值和模板联系起来,在模板的内嵌表达式中,我们输出生日组件的值是通过管道操作符“|”和其右边的内置管道Data Pipe方法来实现的。至于管道的参数,我们在内置管道Data Pipe方法后边加冒号(:)来添加参数值,并且如果有多个参数的话,我们用多个冒号来区分开参数就好了。
最后要说一下的是,angular2管道可以链式运用。我们可以将多个管道通过“|”链式的书写到一个实用的组合体上,如我们将birthday链到DatePipe和UpperCasePipe上以便我们将生日日期显示为大写,下面的日期将会是APR 15, 1988:
The chained hero's birthday is {{ birthday | date | uppercase}}
1.2 管道的内置方法 为了方便使用,Angular2针对之前的经验,设置了一套常用的内置管道,如DatePipe,JsonPipe,UpperCasePipe, LowerCasePipe,CurrencyPipe,PercentPipe及SlicePipe.其目的是在任何模板中都可以便捷使用。我们将详细介绍他们的具体用法。 DatePipe是对日期\时间数据进行格式变换,在模板中直接使用date来引用DatePipe,参数用来指定所需的格式,需要说明的是,不需要再在视图组件中声明,{{day | date: 'yyMMdd'}}
JsonPipe是将Json数据对象转换成字符串格式输出,在模板中使用json来引用JsonPipe,其实现是基于JSON.stringify(),这个管道主要用来调试。{{key1: "value1", key2: "value2"}} | json
UpperCasePipe&LowerCasePipe用于将输入的字符串转换成大小写,在模板中直接使用uppercase&lowercase即可。{{“this is a demo” | uppercase}} | json
CurrencyPipe是将获取到的金钱数转换成特定格式的数字,在模板中直接使用currency来引用CurrencyPipe。{{price | currency: 'USD': true}}
PercentPipe是将数值转换成百分比,在模板中使用percent来引用PercentPipe即可。{{1.23456 | percent: '1.2-3'}} | json
例子中的“:'1.2-3'”表示调用这个这个管道时传入的参数为“'1.2-3'”,对于PercentPipe,这三个数字分别依次表示最少整数位、最少小数位和最多小数位。SlicePipe是用来提取输入字符串中的指定切片,在模板中使用slice来引用SlicePipe。第一个参数指定切片的起始索引,第二个参数指定切片的终止索引的下一个。
{{ '01234567890' | slice:1:4 }}
2.自定义管道 通过上一节的内置管道可以看出,angular2内置的管道并不是特别的丰富,更进一步的是angular2允许自定义管道。自定义一个管道需要以下两个步骤:2.1、声明元数据
和实现一个组件类似,一个自定义的管道也是具有特定元数据的类,如
import {Component,Pipe} from "angular2/core";
@pipe({name: "anyPipeName"})
class anyPipeNamePipe {...}
Pipe注解为被装饰的类附加了管道元数据,其最重要的属性是name,也就是我们在模板中调用这个管道时使用的名称。上面定义的管道,我们可以在模板中这样使用:
{{ data | anyPipeName }}
2.2 实现transform方法 定义一个自定义的管道必须实现一个预定的方法transform(input,args),其中这个方法的input参数代表输入数据,args参数代表输入参数,返回值将被作为管道的输出。import {Component,Pipe} from "angular2/core";
@pipe({name: "anyPipeName"})
class anyPipeNamePipe {
transform(input,args){
return ...;
}
}
通过以上定义一个自定义的管道,需要说明的是这样的一个pipe需要以下这样几个关键的点:
管道是一个带有pipe元数据的类;
这个类实现一个转换方法,通过一个输入值和一个可选的数组字符参数,最终返回转换后的值;
数组参数中的某一项将每一个参数传递给pipe;
我们通知Angular这是一个引入过Angular核心库的@pipe服务
这个@pipe服务带有一个参数,该参数它的值是一个pipe名,我们将使用在一个模板表达式中,它可以是一个合法的Javascript定义。
最后我们通过例子来说明自定义管道的使用,但是需要特别注意的是:
在组件的模板中使用自定义管道之前,需要预先声明一下,即使用Component注解的pipes属性进行声明:pipes:[EzPipe],以便Angular2注入。
如果我们忽视去列出我们的自定义pipe,Angular2将会报错。我们不需要在先前的例子中列出内置指令是因为所有Angular2内置的pipes是预先注册过的,自定义的pipes必须手动注册。
自定义管道完整的例子如下:
import {Component,Pipe} from "angular2/core";
import {bootstrap} from "angular2/platform/browser";
@pipe({name:"title"})
class TitlePipe{
transform(input,args){
return input.split(" ")
.map(word => word[0].toUpperCase() + word.slice(1))
.join(" ");
}
}
@component({
selector:"Demo-app",
template: <p>{{text | title}}</p>
,
pipes : [TitlePipe]
})
class DemoApp{
constructor(){
this.text = "what a wonderful world!";
}
}
bootstrap(DemoApp);
3.管道状态
3.1 无状态的管道
无状态的管道是一个纯粹的方法,流入的数据将不会记录任何东西,或者不会导致任何的副作用。大多数的管道是无状态的,例如我们之前例子的Datapipe就是一个无状态的pipe。据我们之前了解到的管道,包括angular2内置的管道,都具有这么一个特点,就是其输出仅仅是依赖于输入,这就是angular2中的无状态管道,对于无状态的管道,当视图组件的输入没有变化时,angular2框架是不会重新计算管道的输出的。
3.2 有状态的管道
有状态的管道在概念上类似于面向对象编程类,它们可以管理数据的变换,例如管道创建一个HTTP请求,存储它的返回和显示结果,就是一个有状态的pipe。需要注意的是,检索或请求数据的管道应该要谨慎使用,因为使用网路数据往往会引入错误的条件,在javascript中处理更优于在模板中处理。我们可以为了特定的后端和基本的异常捕获而创建自定义的pipe来减轻任何风险。
angular2对有状态的管道定义的关键在于使用使用Pipe注解的属性“pure”,并设置该属性的值为false即可,其作用是要求angular2框架在每个变化检查周期都执行管道的transform()方法。下面我们给一个例子,实现一个10到0的倒数计时器。
import {Component,Pipe} from "angular2/core";
import {bootstrap} from "angular2/platform/browser";
@pipe({
name : "countdown",
pure : false
})
class CountdownPipe {
transform(input){
this.initOnce(input);
return this.counter;
}
initOnce(input){
this.counter = input;
this.timer = setInterval(() => {
this.counter--;
if(this.counter === 0)
clearInterval(this.timer);
}, 1000);
}
}
@component({
selector:"demo-app",
template:<h1>this is a stateful pipe : {{ 10 | countdown }}</h1>
,
pipes : [CountdownPipe]
})
class DemoApp{}
bootstrap(DemoApp);
从这个例子中可以看出,自定义管道countdownPipe的输出不仅依赖输出,还依赖与其内部的变化或者运行状态。
而angular2中,AsyncPipe是有状态管道的一个标志性的例子,AsyncPipe它的输入是一个异步对象:Promise对象、Observable对象或者EventEmitter对象,并且自动的订阅(subscrib)输入对象,最终每当异步对象产生新的值,AsyncPipe会返回这个新的值,它的有状态性是因为pipe维护一个输入的订阅并且它的返回值也依赖于这个订阅器。下面给出的例子,我们将用AsyncPipe绑定一个简单的promise给一个view。
import {Component} from 'angular2/core';
// Initial view: "Message: "
// After 500ms: Message: You are my Hero!"
@component({
selector: 'hero-message',
template: 'Message: {{delayedMessage | async}}',
})
export class HeroAsyncMessageComponent {
delayedMessage: Promise = new Promise((resolve, reject) => {
setTimeout(() => resolve('You are my Hero!'), 500);
});
}
3.3 管道无状态和有状态的区别
管道的有状态和无状态的区别,关键在于是否是需要Angular2框架在输入不变的情况下依然持续地进行变化检测,而angular2的无状态的管道是依赖输入的,即同样的输入,总是产生同样的输出。举个例子,例如我们上面的管道,当我们输入一个默认的数字后,输出值依赖其内部的运行状态变化,而无状态的管道,例如一个加减乘除的管道,在Angular2中,它被视为无状态的,因为它的一次输入不会产生多次输出。
并发测试:
工具:apache
下载链接:http://httpd.apache.org/
安装说明:https://jingyan.baidu.com/article/29697b912f6539ab20de3cf8.html
ab -n1000 -c10 http://localhost:2015/
(1)-n:总请求数,
-c:并发数,Concurrency[kən'kʌrənsi](并发性)。
-t:测试进行的总时间,-p:post数据文件,-w:以html表格形式输出文件。
(2)2015后要加/
<!DOCTYPE HTML>
<html ng-app="test">
<head>
<meta charset="UTF-8">
<script src="F:/angular-1.4.1/angular.js"></script>
<script src="./jquery.js"></script>
<title>ajaxJSON</title>
</head>
<body ng-controller="testController">
<div ng-repeat="per in obj">
<p>{{per.name}}</p>
</div>
<script>
var obj;
var app = angular.module("test",[]);
var jsonobj = $.ajax({
async : false,
type : "GET",
url : "test.json", //使用http-server模拟服务
dataType : "json",
success :function(json){
obj = json;
}
});
app.controller("testController",function($scope){
$scope.obj = obj;
})
</script>
</body>
</html>
test.json
[
{
"name":"zhangsan",
"age":12,
"school":"shenyang school"
},
{
"name":"lisi",
"age":13,
"school":"dalian school"
},
{
"name":"wangwu",
"age":14,
"school":"anshan school"
},
{
"name":"maliu",
"age":15,
"school":"yingkou school"
}
]
一、几种居中方式
1)水平居中
1、块内元素中的行内元素
text-align: center
2、内部元素是块级元素(不能脱离文档流)
margin: 0 auto(前提是宽度有具体的值)
3、脱离文档流
top、left各为50%,margin-top设置为负的高度的一半,margin-left设置为负的宽度的一半
也可以使用绝对定位来处理(设置了固定宽度):
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
----为块区域设置top: 0; left: 0; bottom: 0; right: 0;将给浏览器重新分配一个边界框,此时该块块将填充其父元素的所有可用空间,所以margin 垂直方向上有了可分配的空间。
4、在不设置 Div 元素的宽度(width)的情况下,如何让 Div 元素居中
最后一种方法,也是最近做响应式web开发时遇到的问题,在不设置宽的的情况下怎么让div居中就是一个问题,下面我就讲一下怎么让不设置宽度的div居中的方法
<div class="wrap">
<div class="inner">让这个div居中</div>
</div>
.wrap {
float: left; /* 自适应内容宽度 */
position: relative;
left: 50%; }.inner {
position: relative;
left: -50%;
2)垂直居中
1、固定高(行内元素)
height和line-height;
2、脱离文档流(不固定宽度)
top:50%,left:50%,transform: translate(-50%, -50%);
3、固定宽度
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
也可以设置父高度为容器的高度一半,即height:50%,再设置子元素高度为父元素外边距的负一半,即:margin-top:-height;
解决跨域的几种方式:
一、直接修改浏览器配置。
二、使用ajax的jsonp方式。
1、jsonp并不是采用xmlhttprequest方式请求的,而是采用动态加载script来实现跨域的。
2、传递一个callback参数给跨域服务端,然后跨域服务端返回数据时会将这个callback参数作为函数名来包裹住json数据即可。服务器端需要对这个回调函数接收,不然也实现不了跨域的。
3、调用跨域服务器上动态生成的js格式文件(不管是什么类型的地址,最终生成的返回值都是一段js代码)
4、img、link、iframe同样也可以实现script一样的跨域。
三、被调用方
服务器端告诉浏览器可以调用。
在服务器端响应头增加字段,可以在中间服务器(ngnix),也可在应用服务器(tomcat)增加。
1) 客户端直接发送给应用服务器tomcat
Access-Control-Allow-Origin
Access-Control-Allow-Methods
1、带cookie的跨域,上面值不能设置为*
2、要实现带cookie的跨域匹配所有域名的话,设置Access-Control-Allow-Origin为请求头里面的origin字段的值,因为发送跨域请求的话,都是存在这个字段的。
3、自定义跨域,设置自定义请求头信息,之后在响应Access-Control-Allow-Header里面设置自定义请求头信息值Access-Control-Request-Headers。
2)通过虚拟主机ngnix配置
通过调用方发送请求到被调用方的ngnix,之后在通过ngnix发送到tomcat。
配置ngnix的host
server{
listen 80;
server_name b.com;
location /{
proxy_pass http://localhost:8080/; //所有的请求转到这个上面,即后面的请求test接口,可以写为
// b.com/test,而不需要写为 http://localhost:8080/test
}
}
同时也需要设置上述响应头字段
四、调用方
1、就是通过被调用方的反向代理服务器转发到调用方的代理服务器上。
2、反向代理: 反向代理是供很多客户端都通过它间接访问不同后端服务器上的资源,而不需要知道这些后端服务器的存在,而以为所有资源都来自于这个反向代理服务器。
ngnix配置如下:
server{
listen 80;
server_name a.com;
location /{
proxy_pass http://localhost:8081/; //客户端域名,通过a.com标记
}
location /ajaxserver{ //相当于后端接口的别名,只需调用ajaxserver就可以访问后端接口,而调用的域
//名就为客户端请求域名(相对路径,前面的域名那就和客户端一样),实现同域
proxy_pass http://localhost:8080/test/; //后端接口
}
}
一、promise
1、promise实现ajax
function ajax(url,type){
return new Promise((resolve,reject) => {
var XHR = new XHRHttpRequest();
XHR.open(type,url,true);
XHR.send();
XHR.onreadystatechange = () => {
if(XHR.readyState == 4) {
if(XHR.status == 200) {
try {
let response = JSON.parse(XHR.responseText);
resolve(response);
} catch(e) {
reject(e);
}
} else {
reject(new Error(XHR.statusText));
}
}
}
});
}
2、普通实现ajax
var XHR = new XMLHttpRequest();
XHR.open('GET', url, true);
XHR.send();
XHR.onreadystatechange = function() {
if (XHR.readyState == 4 && XHR.status == 200) {
result = XHR.response;
console.log(result);
}
}
1、 安装nodejs;
2、安装jdk;
3、安装ant,cordova打包是使用ant脚本完成的;
4、git,为了下载插件
5、安装cordova,
npm install -g cordova
安装出现:shasum check failed for错误,镜像问题,需首先配置镜像仓库
npm config set registry="http://registry.cnpmjs.org"
6、安装Android SDK
设置ANDROID_HOME环境变量,指定为Android SDK安装路径
同时也建议你添加Android SDK的tools和platform-tools目录到你的PATH
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.