1、Factory注入到不同的controller时只实例化了一次
var app = angular.module('app',[]);
app.service('helloWorldService', function(){
this.hello = function() {
return "Hello World";
};});
app.factory('helloWorldFactory', function(){
return {
hello: function() {
return "Hello World";
}
}});
service 的构造函数只在声明时被实例化一次
factory 对象每次被注入时各种互相引用,只是被实例化了一次
所有的 providers 都是单例的。
一个factory可以是一个用于创建其他对象的对象。
2、 url路由参数的写法
$stateProvider.state('inbox', {
url: '/inbox/:inboxId',
template: '<h1>Welcome to your inbox</h1>',
controller: function($scope, $stateParams) {
$scope.inboxId = $stateParams.inboxId;
}
});
//另外的写法:
//url: '/inbox/{inboxId}' 匹配更精确,且可以加正则表达式{indexId:正则表达式}
//url: '/inbox?sort' 匹配如/inbox?sort=sending形式的路由
3、嵌套路由
4、scope.$id
angular通过scope $id 获取对应的DOM元素
5、 timeout定时器服务返回一个promise timeOut.cancel()
$scope.$watch('filterOptions', function (newVal, oldVal) {
if (newVal !== oldVal) {
if (timeout) $timeout.cancel(timeout);
timeout = $timeout(function() {
//相关操作
}, 800);
}
}, true);
6、 表单元素的属性指令的require为ngModel读取属性值
7、ngModel.$setValidity的用法
8 、controller和link的分工
(1)在controller写业务逻辑(我们明白业务逻辑大部分是放在服务中),这里所说的业务逻辑乃是为呈现视图之前而准备的数据或者是与其他指令进行数据交互而暴露这个api。
(2)在link中主要操作DOM。
9、indexedDB
- onupgradeneeded
触发条件:第一次打开页面初始化数据库或者版本号发生变化 - onsuccess
触发条件:页面之前被打开过且版本号没有变化 - onerror
触发条件:有错误发生时 - onblocked
触发条件:之前没有关闭连接 - createObjectStore
创建表 - add
新增数据
var transaction = db.transaction(['students'],'readwrite');
transaction.oncomplete = function(event){
console.log('success');
}
transaction.onerror = function(event){
console.log('Error');
}
var objectStore = transaction.objectStore('students');
objectStore.add({rollNo:rollNo,name:name});
- delete
db.transaction(['students'],'readwrite').objectStore('students').delete(rollNo);
- get
var transaction = db.transaction(['students'],'readwrite');
var objectStore = transaction.objectStore('students');
var request = objectStore.get(rollNo);
- put
objectStore.put(request.result);
- 实例化数据库对象
var myDB = {
name:'test',
version:3,
db:null
}
10、webwork
Web Workers 是一种不是在页面线程而是在后台线程中执行脚本的技术。
Web Workers 的优点在于可以将那些复杂的计算过程放在一个单独的后台线程中执行,进而使得主线程(通常是UI线程)能够不被阻塞,也不会被减缓。
通常来说,后台线程 – 包括 worker – 无法操作 DOM。 如果后台线程需要修改 DOM,那么它应该将消息发送给它的创建者,让创建者来完成这些操作。
由于 web worker 位于外部文件中,它们无法访问window对象,document对象
分为专用线程 Dedicated Worker和共享线程 Shared Worker
相关方法:
new Worker('');
.onmessage 接收数据,参数为event
.addEventListener
.postMessage()发送数据,参数为传递的数据
.terminate()销毁线程
//创建worker
var myWorker = new Worker("another.js");
//worker监听
myWorker.onmessage = function(event){
document.getElementById("result").innerHTML = event.data;
}
//另一种写法
myWorkder.addEventListener("message",function(oEvent){
document.getElementById('result').innerHTML = event.data;
},false)
myWorker.postMessage("开始数据");
myWorker.postMessage({"cmd":"init","timestamp":Date.now()});
function stopWorker(){
myWorker.terminate();
}
//another.js
var i=0;
function timedCount(){
i=i+1;
postMessage(i);
setTimeout("timedCount()",500);
}
timedCount();
onmessage = function(oEvent){
postMessage('Hi' + oEvent.data)
}
11、定义弹窗
//定义弹窗
$scope.myPopup = {//判断弹窗的打开或关闭
'isPopup':false
};
// 弹窗
$scope.openType=function() {//打开弹窗
// 一个自定义弹窗
$scope.optionsPopup = $ionicPopup.show({
title: '请选择',
templateUrl: 'assets/tempHtml/carType.html',//弹窗的html片段
scope: $scope
});
$scope.myPopup = {
'isPopup':true
};
$timeout(function(){//定时器关闭
$scope.optionsPopup.close();
},3000);
}
app.directive('closePopupBackDrop', ['$ionicGesture',function($ionicGesture) {
return {
scope: false,//共享父scope
restrict: 'A',
replace: false,
link: function(scope, element, attrs, controller) {
//要在html上添加点击事件, 试了很久- -!
var $htmlEl= angular.element(document.querySelector('html'));//自定义命令放在的html中的元素
$ionicGesture.on("touch", function(event) {//触摸事件
if (event.target.nodeName === "HTML" && scope.myPopup.isPopup) {//判断是否打开
scope.optionsPopup.close();//打开就关闭
scope.myPopup.isPopup = false;//改变状态值
}
},$htmlEl);
}
};
}]);
12、js方法
toFixed()
var num = 10; alert(num.toFixed(2)); //10.00 var num1 = 10.005; lert(num1.toFixed(2)); //10.01
取整
floor:向下取整 round:四舍五入取整 ceil:向上取整
最值
Math.max() Math.min() //接收任意个数值参数 巧用apply与Math的方法找数组的最值 var arr = [3,2,6,1,7,0,8]; var max = Math.max.apply(Math,arr);
过滤
map()和filter() 把传入的依次作用于数组中的每个元素,不同之处在于filter根据返回值是true还是false决定元素的去留,而map()返回真实结果
//数组去重
//方法1
var arr2 = [1,3,2,1,5,2,4];
var newarr2 = arr2.filter(function(element,index,self){
return self.indexOf(element)==index;
})
//方法2
Array.prototype.unique = function(){
var a = []; //临时数组
for(var i=0;i<this.length;i++){
if(a.indexOf(this[i])==-1){
a.push(this[i]);
}
}
return a;
}
//方法3
var temp = [1,1,2,2,33,'33',44,'44'];
var set = new Set(temp);
console.log(set);
var set1 = Array.from(new Set([1,1,2,2,33,'33',44,'44'
]));
console.log(set1);
//闭包
function count(){
var arr = [];
for(var i=1;i<=3;i++){
arr.push(function(n){
return i*i;
});
}
reutrn arr;
}
var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];
//结果16
13、小技巧
//不申明第三个变量,交换两数的位置
//x+=y; y=x-y; x-=y;
//y=[x,x=y][0] 万能转换
//获取对象的key值
var foo = {
'alpha': 'puffin',
'beta': 'beagle'
};
var keys = [],
i = 0;
for (keys[i++] in foo) {
}
console.log(keys);
14、less
//背景图片循环
.bgimgwhile(@counter) when(@counter<5){
.bgimg-@{counter}{
background:url(../images/bgimg-@{counter}-3x.png) no-repeat;
background-size:cover;
}
.bgimgwhile((@counter+1));
}
//定义变量
@mySelector:banner;
.@{mySelector}{
font-weight:bold;
line-height:40px;
……
}
//Mixins
.borderRadius(@radius){
-moz-border-radius: @radius;
-webkit-border-radius: @radius;
border-radius: @radius;
}
#header {
.borderRadius(10px); /*把10px传给变量@radius*/
}
.btn {
.borderRadius(3px);/*把3px传给变量@radius*/
}
.boxShadow(@x:0,@y:0,@blur:1px,@color:#000){
-moz-box-shadow: @arguments;
-webkit-box-shadow: @arguments;
box-shadow: @arguments;
}
#header {
.boxShadow(2px,2px,3px,#f36);
}
//生命周期
查找变量的顺序是先在局部定义中找,如果找不到,则查找上级定义,直至全局。
15、nodejs
//脚本模式
node 文件名.js
//交互模式
node
.exit
//创建node应用
var http = require('http');
http.createServer(function(request,response){
response.writeHead(200,{'Content-Type':'text/plain'});
response.end('Hello World\n');
}).listen(8888);
console.log('listen 127.0.0.1:8888');
//升级npm
sudo npm install npm -g
npm install express -g
npm uninstall express
npm update express
npm search express
npm init
npm install -g cnpm --registry=https://registry.npm.taobao.org
ctrl + c - 退出当前终端。
ctrl + c 按下两次 - 退出 Node REPL。
ctrl + d - 退出 Node REPL.
//非阻塞
var fs = require("fs");
fs.readFile('input.txt', function (err, data) {
if (err) return console.error(err);
console.log(data.toString());
});
console.log("程序执行结束!");
Node 所有 API 都支持回调函数。
单进程单线程应用程序
Node.js 的每一个 API 都是异步的,并作为一个独立线程运行,使用异步函数调用,并处理并发
Node.js基本上所有的事件机制都是用设计模式中观察者模式实现
// 引入 events 模块
var events = require('events');
// 创建 eventEmitter 对象
var eventEmitter = new events.EventEmitter();
// 绑定事件及事件的处理程序
eventEmitter.on('eventName', eventHandler);
// 触发事件
eventEmitter.emit('eventName');
var events = require('events');
var eventEmitter = new events.EventEmitter();
//创建事件处理程序
var connectHandler = function connected(){
console.log('连接成功');
//触发data_received事件
eventEmitter.emit('data_received');
};
//绑定connection事件处理程序
eventEmitter.on('connection',connectHandler);
//使用匿名函数绑定data_received事件
eventEmitter.on('data_received',function(){
console.log('数据接收成功。');
});
//触发connection事件
eventEmitter.emit('connection');
console.log('程序执行完毕');
EventEmitter 对象
//event.js 文件
var events = require('events');
var emitter = new events.EventEmitter();
emitter.on('someEvent', function(arg1, arg2) {
console.log('listener1', arg1, arg2);
});
emitter.on('someEvent', function(arg1, arg2) {
console.log('listener2', arg1, arg2);
});
emitter.emit('someEvent', 'arg1 参数', 'arg2 参数');
//EventEmitter对象的方法
var events = require('events');
var eventEmitter = new events.EventEmitter();
//监听器
var listener1 = function listener1(){
console.log('监听器1');
}
var listener2 = function listener2(){
console.log('监听器2');
}
//绑定connection事件
eventEmitter.addListener('connection',listener1);
eventEmitter.on('connection',listener2);
var eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');
console.log(eventListeners+'个监听连接事件');
eventEmitter.emit('connection');
eventEmitter.removeListener('connection',listener1);
console.log('listener1不再被监听');
eventEmitter.emit('connection');
eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');
console.log(eventListeners+'个监听连接事件');
console.log('程序执行完毕');
Buffer对象
支持的编码为ascii, utf8,utf16le,ucs2, base64 和 hex
buf = new Buffer(); 参数可以是数字、数组、字符串,默认编码utf-8
//写入数据
buf.write(string[, offset[, length]][, encoding])
//读取数据
buf.toString([encoding[, start[, end]]])
//json对象
var json = buf.toJSON(buf);
//缓冲区合并
Buffer.concat(list[, totalLength])
//缓冲区对比
buf.compare(otherBuffer);
//拷贝缓冲区
buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]])
//缓冲区裁剪
buf.slice([start[, end]])
//缓冲区长度
buf.length;
读取流事件
var fs = require('fs');
var data = '';
//创建可读流
var readerStream = fs.createReadStream('input.txt');
//设置编码utf8
readerStream.setEncoding('UTF8');
//处理流事件
readerStream.on('data',function(chunk){
data += chunk;
});
readerStream.on('end',function(){
console.log(data);
})
readerStream.on('error',function(){
console.log(err.stack);
})
console.log('程序执行完毕');
var fs = require('fs');
var data = 'node写入数据';
//创建一个可写入的流
var writerStream = fs.createWriteStream('output.txt');
//使用utf8编码写入数据
writerStream.write(data,'UTF8');
//标记文件末尾
writerStream.end();
//处理流事件
writerStream.on('finish',function(){
console.log('写入完成');
});
writerStream.on('error',function(){
console.log(err.stack);
});
console.log('程序执行完毕')
管道流
var fs = require("fs");
// 创建一个可读流
var readerStream = fs.createReadStream('input.txt');
// 创建一个可写流
var writerStream = fs.createWriteStream('output.txt');
// 管道读写操作
// 读取 input.txt 文件内容,并将内容写入到 output.txt 文件中
readerStream.pipe(writerStream);
console.log("程序执行完毕");
链式流应用:解压缩文件
var fs = require('fs');
var zlib = require('zlib');
//压缩input.txt文件为input.txt.gz
fs.createReadStream('input.txt')
.pipe(zlib.createGzip())
.pipe(fs.createWriteStream('input.txt.gz'));
console.log('文件压缩完成');
模块系统
//hello.js
function Hello(){
var name;
this.setName = function(theName){
name = theName;
}
this.sayHello = function(){
console.log('Hello'+name);
}
}
module.exports = Hello;
//main.js
var Hello = require('./hello');
hello = new Hello();
hello.setName('Byviod');
hello.sayHello();
http、fs、path等,原生模块。
./mod或../mod,相对路径的文件模块。
/pathtomodule/mod,绝对路径的文件模块。
mod,非原生模块的文件模块。
require加载
nodjs路由
http://localhost:8888/start?foo=bar&hello=world
url.parse(string).query (start?foo=bar&hello=world)
url.parse(string).pathname(start)
querystring(string)[“foo”] bar
nodejs全局对象
__filename
__dirname
process
util.inherits实现对象继承
util.inherits(Sub,Base);//继承范围为Base.prototype
node文件系统
var fs = require("fs");
fs.readFile()
fs.open(path, flags[, mode], callback)
fs.stat(path, callback)
fs.writeFile(filename, data[, options], callback)
fs.read(fd, buffer, offset, length, position, callback)