首页 > 代码库 > 7_nodejs angularjs

7_nodejs angularjs

 

 

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 = http://www.mamicode.com/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="http://www.mamicode.com/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="http://www.mamicode.com/img/{{url}}"          <img ng-src="http://www.mamicode.com/img/{{dish.url}}" />

err-src="http://www.mamicode.com/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="http://www.mamicode.com/#/路由地址">...</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);

}

}

})

7_nodejs angularjs