我是卡卡卡颂


  • 首页

  • 归档

  • 标签

node源码实现——pipe

发表于 2016-08-28

pipe作用

1
readable.pipe(destination, [options])
  • 该方法从可读流中拉取所有数据,并写入到所提供的目标。该方法能自动控制流量以避免目标被快速读取的可读流所淹没。

    功能点分析

  1. 该方法实现了一个可读流向一个可写流数据的写入
  2. 这种写入方法可以控制liul

    实现原理

  3. 定义可读流与可写流,监听data事件当数据读入缓存后写数据
  4. 判断可写流是否超过写的限制。如果超过,暂停数据读入。并监听可写流drain事件判断数据是否写入。
  5. 数据写入后恢复数据读入,并循环第一步。
  6. 监听可读流end事件,当数据读入完毕,将缓存区的数据强制写入。

    代码实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    function pipe1 (source,target) {
    var fs=require('fs');
    var ws=fs.createWriteStream(target);
    var rs=fs.createReadStream(source);
    var flag=true;
    //监听data,开始读取数据
    rs.on('data',function (data) {
    //写入数据
    flag=ws.write(data,function (err) {
    console.log(err);
    });
    //如果无法写入,暂停读入
    if (!flag) {
    rs.pause();
    }
    })
    //监听drain事件,判断是否写入完毕
    ws.on('drain',function () {
    rs.resume();
    })
    //监听end,判断读入完毕,将数据强制写入
    rs.on('end',function (data) {
    ws.end(data);
    })
    //错误监听
    rs.on('error',function (err) {
    console.log(err);
    })
    }

angular自定义指令取得控制器数据的方法

发表于 2016-08-25

为什么

  • 一般我们自定义指令,是为了封装一整段DOM结构或作操作DOM的方法,涉及到编译新DOM树。所以必须获得编译前DOM结构作用域的数据才能对其作出改变。但是我们的自定义指令的作用域并不是DOM结构的作用域,所以必须通过一些方法来获得DOM作用域。接下来是方法总结。

    通过自定义指令的scope属性

  • 数据按类型可以分为三类:字面量、变量、方法。在directive中的scope属性提供了3种操作符来分别获得这三种数据。获取的流程相同,主要是不同的操作符。
  • 字面量的获取
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <div ng-controller="myCtrl">
    myCtrl:<input type="text" ng-model="name">
    my-dir:<my-dir name="{{name}}"></my-dir>
    </div>
    <script>
    var myApp=angular.module('myApp',[]);
    myApp.controller('myCtrl',['$scope',function ($scope) {
    $scope.name='KOBE';
    }])
    myApp.directive('myDir',function () {
    return {
    template:'<input type="text" ng-model="name1">',
    scope:{
    name1:'@name'
    }
    }
    })
  1. 首先在编译前的DOM结构中

    1
    2
    3
    4
    <div ng-controller="myCtrl">
    myCtrl:<input type="text" ng-model="name">
    my-dir:<my-dir name="{{name}}"></my-dir>
    </div>

    由于my-dir与input同属myCrl控制器,所以my-dir中的name可以取得控制器中的,也就是input标签中ng-model所绑定的name。

  2. name保存在自定义指令scope属性中的@name中。

    1
    2
    3
    4
    5
    6
    7
    8
    myApp.directive('myDir',function () {
    return {
    template:'<input type="text" ng-model="name1">',
    scope:{
    name1:'@name'
    }
    }
    })

    其中@符号代表该数据是字面量。将其值赋给name1.(这里如果name:’@name’可以简写为name:’@’.)

  3. 将name1赋给模板中的ng-model属性。

    1
    template:'<input type="text" ng-model="name1">',

这样编译后的DOM结构中ng-model就得到编译前input中保存的name。

  • 变量的获取

字面量与变量的区别

1
2
3
4
<!--字面量-->
my-dir:<my-dir name="{{name}}"></my-dir>
<!--变量-->
my-dir:<my-dir name="name"></my-dir>

这里my-dir中name获得的是控制器作用域中的$scope.name变量而不是$scope.name所对应的值。
与前面字面量数据的获得唯一的区别在于第二步将’@’符号改为’=’,即

1
2
3
4
5
6
7
8
myApp.directive('myDir',function () {
return {
template:'<input type="text" ng-model="name1">',
scope:{
name1:'=name'
}
}
})

-方法的获取
方法的获取符号为”&”。有一点坑在于如果方法需要传参,需要用对象的方式来赋值

1
2
3
4
5
6
7
8
9
//编译前的模板
my-dir:<my-dir name="nameDir" greet="greetCtrl(d)"></my-dir>
//directive中的参数
template:'<input type="text" ng-model="nameDir"> <button ng-click="greetDir({d:nameDir})">点我</button>',
scope:{
nameDir:'=name',
greetDir:'&greet'
},

通过ng-transclude获取数据

  • 在指令属性中设置transclude:true,

angular--服务

发表于 2016-08-25

什么是服务

  • 服务是公用的方法,可以把控制器中相同的部分抽取出来封装成一个服务,需要的时候注入控制器。

服务的分类

  • 服务分为内置服务与自定义服务

常见内置服务

  1. $http服务用来向后台请求数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    var mod=angular.module('m',[]);
    mod.controller('myCtrl',function ($scope,$http) {
    // 注入http服务
    // $http用来向后台请求数据
    $http({
    url:'http.json',
    method:'GET',
    params:{data:'aaaa'} //只是对于GET请求使用,在问号后面传递参数
    //method:'POST',
    //data:{}
    }).success(function (data,status,headers,config) {
    // 当成功时执行success方法中的回调函数
    // data 请求回来的数据
    // status 状态码
    // headers是一个方法,执行时可看到头部信息
    // config 配置信息,包含以上三者
    console.log(data,status,headers,config);
    }).error(function (err) {
    // 当失败时执行error中的回调函数
    // err错误信息
    })
    })
    //$http返回的是一个promise (用来解决异步)
    // 封装的简便方法
    // $http.get() $http.delete()
    // 参数1 路径字符串 参数2 config 对象,放配置内容
    // $http.post() $http.put()
    // 参数1 路径字符串 参数2 请求体data 参数3 config
    // $http.jsonp() (实现跨域请求,其回调函数名 JSON_CALLBACK)
    // 参数 请求路径
    // $http.delete()
    // $http.put()
  2. \$interval与$timeout 设定计时器,不同于原生计时器在于其可触发脏值查询,调用其cancel方法清除计时器

1
2
3
4
5
6
7
8
9
10
var newMod=angular.module('newm',[]);
newMod.controller('ctrl',function ($scope,$interval,$timeout) {
$scope.age=8;
$interval(function () {})
$scope.fn=function () {
$timeout.cancel(timer);
var timer=$timeout(fn,1000);
// 未完
}
})

五种自定义服务

  1. provider是最全面的自定义服务,注入的是服务实例上$get方法的返回值,可以暴露方法作为API,模块的config方法接受服务名+Provider参数,该参数是服务的一个实例,可以对暴露的API进行配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    var myModule = angular.module('myModule', []);
    //配置名为myPro的服务
    myModule.provider('myPro',function () {
    var currency='$';
    this.setCurrency=function (a) {
    currency=a;
    };
    this.$get=function () {
    return {
    '+':function (a,b) {
    return currency+(Number(a)+Number(b));
    }
    }
    }
    })
    // 配置函数,对服务暴露出来的接口进行配置,函数中传递的参数是
    // 服务名+provider
    // myProvider是my服务的实例
    myModule.config(function (myProProvider) {
    myProProvider.setCurrency('¥');
    })
    // 注入自定义服务
    myModule.controller('myCtrl',['$scope','myPro',function ($scope,myPro) {
    //注入的是服务的实例$get方法的返回值
    $scope.result=myPro['+'](1,2);
    }])
  2. factory 最常用定义服务的方法.内部封装的也是provider,函数定义部分只要返回值,不能调用config配置函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    var myModule = angular.module('myModule', []);
    // 注入自定义服务 注入的是factory返回值
    myModule.factory('myPro',function () {
    return {
    '+':function (a,b) {
    return (Number(a)+Number(b));
    },
    '-':function (a,b) {
    return (a-b);
    }
    }
    })
    myModule.controller('myCtrl',['$scope','myPro',function ($scope,myPro) {
    $scope.cal=function () {
    $scope.result=myPro[$scope.val]($scope.one,$scope.two);
    }
    }])
  3. service 相当于原生js中的构造函数,向控制器注入服务的时候,注入的是该方法的一个实例,不能调用配置函数config

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    var myModule = angular.module('myModule', []);
    myModule.controller('myCtrl',['$scope','myPro',function ($scope,myPro) {
    $scope.result=myPro['*'](3,5);
    }])
    myModule.service('myPro',function () {
    this['+']=function (a,b) {
    return (Number(a)+Number(b));
    };
    //ES6写法 箭头函数
    this['*']=(a,b)=>a*b;
    })
  4. value用来定义变量,也可以作为服务注入到控制器中,不能在配置函数中调用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var myModule = angular.module('myModule', []);
    //相当于把myPro赋值为'123'
    myModule.value('myPro','123');
    myModule.controller('myCtrl',['$scope','myPro',function ($scope,myPro) {
    $scope.result=myPro;
    }])
  5. constant 定义常量,用法同value.与value不同点在于可以注入到配置函数中

angular 自定义指令取得控制器中数据的方法

发表于 2016-08-24

这是一个问题

我们知道$scope作用域中可以定义值、变量、方法。而我们子定义模板中link方法的形参只能取得模板所在作用域的值、变量、方法。我们如何在模板中取得模板所在控制器作用域中的数据呢。

数据大不同

  • 数据可以分为固定的值、变量、方法。这三者的获取方法是不同的。

固定值的获取,代码提供

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html >
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>scope 取得控制器作用域中的值</title>
</head>
<body>
<div ng-controller="myCtrl">
myCtrl:<input type="text" ng-model="name">
my-dir:<my-dir name="{{name}}"></my-dir>
</div>
<script src="angular.js"></script>
<script>
var myApp=angular.module('myApp',[]);
myApp.controller('myCtrl',['$scope',function ($scope) {
$scope.name='珠峰培训';
}])
myApp.directive('myDir',function () {
return {
template:'<input type="text" ng-model="name1">',
scope:{
name1:'@name'
}
}
})
</script>
</body>
</html>
  1. 定义name属性,取得上级控制器作用域中的name值

    1
    my-dir:<my-dir name="{{name}}"></my-dir>
  2. 模板scope对象中定义name1属性,其中@name等于上一级取得的name值。这样模板中name1属性就取得了上级控制器作用域中的name属性

    1
    2
    3
    scope:{
    name1:'@name'
    }
  3. 将第二步保存的name1赋给模板DOM中

    1
    template:'<input type="text" ng-model="name1">',

##自定义模板取得控制器中变量的方法

  1. 将上面第一步中 name=”“ 改为name=”name”,使得取得的是变量
  2. 将上面第二步中 name1:’@name’ 改为 name:’=name’,取得第一步取得的值

##自定义模板取得控制器中方法的方法

  1. 将上面第一步中 name=”“ 改为name=”name”,使得取得的是变量
  2. 将上面第二步中 name1:’@name’ 改为 name:’=name’,取得第一步取得的值

注意事项

- name="{{name}}"中{{name}}保存的是name变量的值,是一个固定的值,无法做到双向绑定
- name="name" 中"name" 保存的是指向控制器中$scope.name,不是固定的,可以双向绑定

angular————方法

发表于 2016-08-23
  1. 方法

    • 方法包括内置方法、模块的方法

      • 常见内置方法
      1. 大小写转换

        1
        2
        angular.uppercase(str)
        angular.lowercase(str)
      2. 全等比较 相当于js中的=== 坑:NaN===NaN //true

        1
        angular.equals(value1,value2)
      3. JSON转换

        1
        2
        angular.toJson() //相当于JSON.stringify
        angular.fromJson() //相当于JSON.parse
      4. 把value2(或其后的参数)中的值添加到value1中,value1改变,其他值不变

        1
        angular.extend(value1,value2);
      5. value1的值覆盖value2的值

        1
        angular.copy(value1,value2);
      6. 遍历 参数3 改变this的指向

        1
        angular.forEach(item,index,参数3)
      7. 参数1 改变this指向 参数2 函数体 参数3往后是传参

        1
        angular.bind()
      8. 类型检测

        1
        2
        3
        angular.isArray();
        angular.isObject();
        angular.isNumber();
      9. 原生对象转化为jQuery对象

        1
        angular.element();
      10. 生成模块 参数1 模块名称 参数2 依赖模块

        1
        var mod=angular.module('name',[])
    • 模块方法

      • 模块即angular调用module方法生成的模块
      • 模块拥有自己的作用域
      • 常见模块方法
      1. 生成控制器 产生自己的作用域
      • 参数1 模块名
      • 参数2 数组 索引1为’$scope’ 索引2至n为导入的服务,最后一个索引为定义模块的函数
        1
        mod.module('ctrl',['$scope','name',function (s,n) {}])
      1. 生成自定义过滤器 方法见过滤器篇
    • $scope作用域方法

      1. $apply :强制刷新,调用$rootScope.$digest 从根作用域开始进行脏值查询
      2. $watch :监听数据改变
      3. $digest :强制刷新,从当前作用域到子作用域
      4. $emit :发射事件 基于事件驱动
      5. $broadcast: 广播事件 基于事件驱动
      6. $on :监听事件

angular————过滤器

发表于 2016-08-23
  1. 过滤器

    • 过滤器的作用是输出经过过滤后的数据
    • 过滤器分为内置过滤器与自定义过滤器
    • 过滤器有3种使用方法

      1. 在表达式中使用 其中|是分隔符 :后面进行传参

        1
        {{name|currency:'¥'}}
      2. 控制器中注入$filter服务

        1
        2
        3
        4
        mod.controller('ctrl',function ($scope,$filter) {
        $scope.name='aaaaabbbbdddd';
        $scope.name=$filter('uppercase')($scope.name);
        })
      3. 过滤器的名字+Filter(如:uppercaseFilter) 如:$filter(‘过滤器名称’)(数据)

        1
        2
        3
        4
        mod.controller('ctrl',function ($scope,uppercaseFilter) {
        $scope.name='aaaaabbbbdddd';
        $scope.name=uppercaseFilter($scope.name);
        })
    • 常见内置过滤器

      1. currency 货币过滤器 如果不传参默认是$,也可以自己传递参数

      2. uppercase lowercase 大小写过滤器

      3. number 限制数字后面小数点位数

      4. limitTo 用来限制字符串、数组的长度

      5. json 把普通对象转换为JSON对象

      6. date 转换时间格式

      7. filter 根据条件过滤数组,将过滤后的内容以一个新数组返回
        -参数1 可以是字符串,也可以是一个方法,根据返回值进行过滤
        -参数2 true严格匹配,false不区分大小写,非严格匹配,默认false
      8. orderBy 数组实现排序,将排序后的数组返回
        -参数1 可以是字符串,按照哪一项来排序
        -参数2 true 倒序,false 正序 默认正序
    • 如何生成自定义过滤器
      • 参数1 过滤器的名字
      • 参数2 函数(定义过滤器的方法)
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        //返回前len项为大写的值的过滤器
        mod.filter('newF',function () {
        // 参数1: input就是要使用该过滤器的数据
        // 从第二个参数开始就是冒号后面传递的参数
        return function (input,len) {
        var a=input.slice(0,len);
        a=angular.uppercase(a);
        var b=input.slice(len);
        return a+b;
        }
        })
        //数组去重的过滤器
        mod.filter('newF',function () {
        return function (input,len) {
        var newarr=[];
        for (var i=0;i<input.length;i++) {
        if (newarr.indexOf(input[i])===-1) {
        newarr.push(input[i]);
        }
        }
        return newarr;
        }
        })

angular————概论 指令 表达式

发表于 2016-08-23

AngularJs是什么

  • AngularJs是一款MVVM结构的前端框架。他分为M-model(数据层),V-view(视图层),VM-viewModel(视图模型层)。其中V与VM实现了双向数据绑定(具体的实现方法是通过内部的$digest也就是脏值查询实现的)。VM与M实现数据的交互

AngularJs能做什么

  • AngularJs通过内部的各种功能实现了在不操作DOM树(当然内部封装指令时会调用DOM方法)的情况下根据需要实时渲染前端页面、与后端交互。并且实现了模块化。是一款在不断的使用中可以不断健壮的框架。

AngularJs怎么做

  • Angular通过各种内部的功能组合实现前端页面实时渲染。具体如下

    1. 指令

      • 凡是以ng-或者data-ng-为前缀的都是angularJS的内置指令
      • 指令分为内置指令和自定义指令,自定义指令通过mod.directive()方法产生
      • 指令有4种调用方法,即“ECMA”。

        • E-element 作为元素标签调用

          1
          <abcd></abcd>
        • C-class 作为类调用

          1
          <div class="abcd"></div>
        • M-comment 作为注释调用,指令内的replace:true,且注释前后有2个空格

          1
          <!-- directive:zfpx -->
        • A-attribute 作为元素属性调用

          1
          <div abcd></div>
      1. ng-app :angular起始位置,会形成$scope根目录
      2. ng-class :两种用法 ‘{true:”c1”,false:”c2”}[flag]’ ‘{c1:flag1,c2:flag2}’
      3. ng-init :初始化数据
      4. ng-if :控制元素是否存在,会形成自己的作用域,如果不存在内部作用域也会销毁
      5. ng-show :控制元素显示隐藏,即使隐藏了内部指令还会执行
      6. ng-hide :与show相反
      7. ng-include :引入html片段
      8. ng-model :用在表单元素上,存储value值,实现数据双向绑定
      9. ng-repeat :迭代DOM元素,会形成自己的作用域。当遍历重复数据会报错, track by $index解决
      10. ng-style :动态增加行内样式
      11. ng-src
      12. ng-href
      13. ng-change
      14. ng-model-options
      15. ng-click
      16. ng-bind
      17. ng-bind-template
      18. ng-cloak :解决闪烁,需要在加载的时候给一个隐藏样式
    2. 表达式

      1
      {{}}
      • 实现DOM中的数据与作用域$scope数据的绑定
      • 可以放文字,变量,运算符,其中变量可以存储字符串、数组、对象等

##Angular 内部运行的三个阶段

  • 加载阶段 :引入angular开始到对指令解析前
  • 编译阶段 : template replac transclude compile
  • 链接阶段 : link实现与作用域的绑定,如果当前没有形成在自己的作用域,scope指向上一级作用域

angular ng-model双向绑定的自定义模板实现

发表于 2016-08-23

angular ng-model双向绑定的自定义模板实现

流程:

  1. 定义模块

    1
    var myApp=angular.module('myApp',[]);
  2. 调用directive 自定义模板方法

    1
    2
    3
    4
    5
    6
    7
    myApp.directive('myModel',function () {
    return {
    link:function (scope,element,attrs) {
    }
    }
    })
  3. link内部实现,第一步拿到input的内容,因为element是jQ对象,

    1
    element.val()
  4. link内部实现,第二步拿到my-model对应的变量名

    1
    attrs['my-model']
  5. link内部实现,在scope上定义对象

    1
    scope[attrs['my-model']]=element.val();
  6. 强制刷新,实现数据双向绑定

    1
    scope.$apply();

完整实现代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>ng-model双向绑定的自定义模板实现</title>
</head>
<body>
<input type="text" my-model="value">{{value}}
<script src="angular.js"></script>
<script>
var myApp=angular.module('myApp',[]);
myApp.directive('myModel',function () {
return {
link:function (scope,element,attrs) {
element.on('keyup',function () {
scope[attrs['myModel']]=element.val();
scope.$apply();
})
}
}
})
</script>
</body>
</html>

angular 自定义指令的配置方法

发表于 2016-08-21

angular 自定义指令的配置方法

自定义模板的作用

封装好需要的方法方便使用

配置属性及用途简介

  1. template:产生一个模板

    1
    template:'<p>我的模板</p>'
  2. templateUrl:引入一个外部模板

    1
    templateUrl:'url.html'
  3. scope:boolean或对象 定义该模板是否产生自己的作用域,如果不定义则为false。如果没有形成自己的作用域,该模板的作用域为父级作用域

  4. replace:boolean 定义该模板是否替换原有DOM结构
  5. restrict:’ECMA’ 定义模板可以使用的方式

    • E:element 作为元素标签调用

      1
      <mytemplate></mytemplate>
    • C:class 作为样式类名调用

      1
      <div class="mytemplate"></div>
    • M:comment 作为注释使用

      1
      <!-- directive:mytemplate -->
    • A:attribute 作为属性名调用

      1
      <div mytemplate></div>
  6. transclude 保存原有标签内的内容,与ng-transclude联合使用 如:

    1
    <p>我是原始DOM结构<span ng-transclude>我是会保留下来的部分</span></p>

    其中带有ng-transclude属性的span标签下的内容会保留
    ps:ng-transclude会形成作用域

  7. link 实现该模板作用域与模板属性、模板DOM元素间的链接,用以封装方法

    1
    2
    3
    4
    5
    6
    7
    /*
    * @param scope 当前模板作用域,如果当前模板没有形成作用域,会直接找父级作用域
    * @param element 当前自定义指令所在的DOM元素,是一个jQ对象,angular内置轻量级jQ,也就是jqLite
    * @param attrs 自定义指令所在的DOM元素上的属性存储在attrs对象中
    */
    link:function (scope,element,attrs) {
    }

配置选项 代码实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var myApp=angular.module('myApp',[]);
myApp.directive('mytemplate',function () {
//定义一个指令,命名是驼峰命名法,使用时用-分割,将大写转为小写
return {
//返回值是对象
template:'<p>我的模板<span ng-transclude></span></p>',
//或者引入外界模板
//templateUrl:'url.html',
//替换掉原有DOM结构
replace:true,
//定义指令可以用的位置,默认:'EA'
restrict:'ECMA',
//启用transclude
transclude:true,
//模板会形成自己作用域
scope:true,
link:function (scope,element,attrs) {
}
}
})

Hello World

发表于 2016-08-21

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

1…45
BetaSu

BetaSu

一言不合撸源码

50 日志
© 2017 BetaSu
由 Hexo 强力驱动
主题 - NexT.Pisces