过滤器

格式化过滤器

用于处理数字或字符串,多用于{{}}或ms-attr或ms-class

注意: avalon的过滤器与ng的过滤器在传参上有点不一样,需要用()括起来

uppercase

将字符串全部大写

  1. vm.aaa = "aaa"
  2. <div>{{@aaa | uppercase}}</div>

lowercase

将字符串全部小写

  1. vm.aaa = "AAA"
  2. <div>{{@aaa | lowercase}}</div>

truncate

对长字符串进行截短,有两个可选参数

number,最后返回的字符串的长度,已经将truncation的长度包含在内,默认为30。truncation,告知用户它已经被截短的一个结尾标识,默认为"…"

  1. vm.aaa = "121323234324324"
  2. <div>{{@aaa | truncate(10,'...')}}</div>

camelize

驼峰化处理, 如"aaa-bbb"变成"aaaBBB"

escape

对类似于HTML格式的字符串进行转义,如将<、 >转换为<、 >

sanitize

对用户输入的字符串进行反XSS处理,去掉onclick, javascript:alert<script>等危险属性与标签。

number

对需要处理的数字的整数部分插入千分号(每三个数字插入一个逗号),有一个参数fractionSize,用于保留小数点的后几位。

fractionSize:小数部分的精度,默认为3。

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>TODO supply a title</title>
  5. <meta charset="UTF-8">
  6. <meta name="viewport" content="width=device-width">
  7. <script src="avalon.js"></script>
  8. <script>
  9. avalon.define({
  10. $id: "number",
  11. aaa: 1234.56789
  12. })
  13. </script>
  14. </head>
  15. <body>
  16. <div ms-controller="number">
  17. <p>输入数字:
  18. <input ms-duplex="@aaa">
  19. </p>
  20. <p>不处理:{{@aaa}}</p>
  21. <p>不传参:{{@aaa|number}}</p>
  22. <p>不保留小数:{{@aaa|number(0)}}</p>
  23. <p>负数:{{-@aaa|number(4)}}</p>
  24. </div>
  25. </body>
  26. </html>

currency

用于格式化货币,类似于number过滤器(即插入千分号),但前面加了一个货币符号,默认使用人民币符号\uFFE5

symbol, 货币符号,默认是\uFFE5fractionSize,小数点后保留多少数,默认是2

date

对日期进行格式化,date(formats), 目标可能是符合一定格式的字符串,数值,或Date对象。

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>TODO supply a title</title>
  5. <meta charset="UTF-8">
  6. <meta name="viewport" content="width=device-width">
  7. <script src="avalon.js"></script>
  8. <script>
  9. avalon.define({
  10. $id: 'testtest',
  11. name: "大跃进右",
  12. d1: new Date,
  13. d2: "2011/07/08",
  14. d3: "2011-07-08",
  15. d4: "01-01-2000",
  16. d5: "03 04,2000",
  17. d6: "3 4,2000",
  18. d7: 1373021259229,
  19. d8: "1373021259229",
  20. d9: "2014-12-07T22:50:58+08:00",
  21. d10: "\/Date(1373021259229)\/"
  22. })
  23. </script>
  24. </head>
  25. <body>
  26. <div ms-controller="testtest">
  27. <p>生成于{{ @d1 | date("yyyy MM dd:HH:mm:ss")}}</p>
  28. <p>生成于{{ @d2 | date("yyyy MM dd:HH:mm:ss")}}</p>
  29. <p>生成于{{ @d3 | date("yyyy MM dd:HH:mm:ss")}}</p>
  30. <p>生成于{{ @d4 | date("yyyy MM dd:HH:mm:ss")}}</p>
  31. <p>生成于{{ @d5 | date("yyyy MM dd:HH:mm:ss")}}</p>
  32. <p>生成于{{ @d6 | date("yyyy MM dd")}}</p>
  33. <p>生成于{{ @d7 | date("yyyy MM dd:HH:mm:ss")}}</p>
  34. <p>生成于{{ @d8 | date("yyyy MM dd:HH:mm:ss")}}</p>
  35. <p>生成于{{ @d9 | date("yyyy MM dd:HH:mm:ss")}} //这是ISO8601的日期格式</p>
  36. <p>生成于{{ @d10| date("yyyy MM dd:HH:mm:ss")}} //这是ASP.NET输出的JSON数据的日期格式</p>
  37. </div>
  38. </body>
  39. </html>
标记说明
yyyy将当前的年份以4位数输出,如果那一年为300,则补足为0300
yy将当前的年份截取最后两位数输出,如2014变成14, 1999变成99, 2001变成01
y将当前的年份原样输出,如2014变成2014, 399变成399, 1变成1
MMMM在中文中,MMMM与MMM是没有区别,都是"1月","2月"……英语则为该月份的单词全拼
MMM在中文中,MMMM与MMM是没有区别,都是"1月","2月"……英语则为该月份的单词缩写(前三个字母)
MM将月份以01-12的形式输出(即不到两位数,前面补0)
M将月份以1-12的形式输出
dd以日期以01-31的形式输出(即不到两位数,前面补0)
d以日期以1-31的形式输出
EEEE将当前天的星期几以“星期一”,“星期二”,“星期日”的形式输出,英语则Sunday-Saturday
EEE将当前天的星期几以“周一”,“周二”,“周日”的形式输出,英语则Sun-Sat
HH将当前小时数以00-23的形式输出
H将当前小时数以0-23的形式输出
hh将当前小时数以01-12的形式输出
h将当前小时数以0-12的形式输出
mm将当前分钟数以00-59的形式输出
m将当前分钟数以0-59的形式输出
ss将当前秒数以00-59的形式输出
s将当前秒数以0-59的形式输出
a将当前时间是以“上午”,“下午”的形式输出
Z将当前时间的时区以-1200-+1200的形式输出
fullDate相当于y年M月d日EEEE 2014年12月31日星期三
longDate相当于y年M月d日EEEE 2014年12月31日
medium相当于yyyy-M-d H:mm:ss 2014-12-31 19:02:44
mediumDate相当于yyyy-M-d 2014-12-31
mediumTime相当于H:mm:ss 19:02:44
short相当于yy-M-d ah:mm 14-12-31 下午7:02
shortDate相当于yy-M-d 14-12-31
shortTime相当于ah:mm 下午7:02

循环过滤器

用于ms-for指令中

limitBy

只能用于ms-for循环,对数组与对象都有效, 限制输出到页面的个数, 有两个参数

  • limit: 最大个数,必须是数字或字符, 当个数超出数组长或键值对总数时, 等于后面
  • begin: 开始循环的个数, 可选,默认0
  1. <script>
  2. avalon.define({
  3. $id: "limitBy",
  4. array: [1, 2, 3, 4, 5, 6],
  5. object: {a: 1, b: 2, c: 3, d: 4, e: 5},
  6. num: 3
  7. })
  8. </script>
  9. <div ms-controller='limitBy'>
  10. <select ms-duplex-number='@num'>
  11. <option>2</option>
  12. <option>3</option>
  13. <option>4</option>
  14. <option>5</option>
  15. </select>
  16. <ul>
  17. <li ms-for='el in @array | limitBy(@num)'>{{el}}</li>
  18. </ul>
  19. <ul>
  20. <li ms-for='el in @object | limitBy(@num)'>{{el}}</li>
  21. </ul>
  22. </div>

orderBy

只能用于ms-for循环,对数组与对象都有效, 用于排序, 有两个参数

  • key: 要排序的属性名
  • dir: -1或1, 顺序或倒序,可选,默认1
  1. <script>
  2. avalon.define({
  3. $id: "orderBy",
  4. array: [{a: 1, b: 33},{a: 2, b: 22}, {a: 3, b: 11}],
  5. order: 'a',
  6. dir: -1
  7. })
  8. </script>
  9. <div ms-controller='orderBy'>
  10. <select ms-duplex='@order'>
  11. <option>a</option>
  12. <option>b</option>
  13. </select>
  14. <select ms-duplex-number='@dir'>
  15. <option>1</option>
  16. <option>-1</option>
  17. </select>
  18. <table border='1' width='200'>
  19. <tr ms-for="el in @array | orderBy(@order, @dir)">
  20. <td ms-for='elem in el'>{{elem}}</td>
  21. </tr>
  22. </table>
  23. </div>

filterBy

只能用于ms-for循环,对数组与对象都有效, 用于获取它们的某一子集, 有至少一个参数

search,如果为函数时, 通过返回true决定成为子集的一部分; 如果是字符串或数字, 将转换成正则, 如果数组元素或对象键值匹配它,则成为子集的一部分,但如果是空字符串则返回原对象 ;其他情况也返回原对象。其他参数, 只有当search为函数时有效, 这时其参数依次是数组元素或对象键值(对象的情况下), 索引值或对象键名(对象的情况下), 多余的参数此过滤多用于自动完成的模糊匹配!

过滤器  - 图1

filterBy例子1

  1. <script>
  2. avalon.define({
  3. $id: "filterBy",
  4. array: ['aaaa', 'aab', 'acb', 'ccc', 'dddd'],
  5. object: {a: 'aaaa', b: 'aab', c: 'acb', d: 'ccc', e: 'dddd'},
  6. searchs: "a",
  7. searchFn: function (el, i) {
  8. return i > 2
  9. },
  10. searchFn2: function (el, i) {
  11. return el.length === 4
  12. },
  13. searchFn3: function (el, i) {
  14. return i === 'b' || i === 1
  15. }
  16. })
  17. </script>
  18. <div ms-controller='filterBy'>
  19. <select ms-duplex='@search'>
  20. <option>a</option>
  21. <option>b</option>
  22. <option>c</option>
  23. </select>
  24. <p><button ms-click="@search = @searchFn | prevent">变成过滤函数</button></p>
  25. <p><button ms-click="@search = @searchFn2 | prevent">变成过滤函数2</button></p>
  26. <p><button ms-click="@search = @searchFn3 | prevent">变成过滤函数3</button></p>
  27. <ul>
  28. <li ms-for='el in @array | filterBy(@search)'>{{el}}</li>
  29. </ul>
  30. <ul>
  31. <li ms-for='el in @object | filterBy(@search)'>{{el}}</li>
  32. </ul>
  33. </div>

filterBy例子2

  1. <body>
  2. <script>
  3. var vm = avalon.define({
  4. $id: 'test',
  5. arr: [{color: 'red'},{color:'green'},{color:'red'}],
  6. fn: function(el, index, xxx){
  7. console.log(el, index, xxx)
  8. return el.color === 'red'
  9. }
  10. })
  11. </script>
  12. <style>
  13. </style>
  14. <div ms-controller="test">
  15. <ul>
  16. <li ms-for="el in @arr | filterBy(@fn, 'xxx')">{{el.color}}</li>
  17. </ul>
  18. </div>
  19. </body>

filterBy例子3

  1. <script>
  2. var vm = avalon.define({
  3. $id: 'test',
  4. arr: [{name: 'wanglin', age: 11},
  5. {name: 'lin', age: 3},
  6. {name: 'Hunt', age: 22},
  7. {name: 'Joe', age: 33}],
  8. fn: function(a){//过滤数组中 name属性值带lin中的元素
  9. return /lin/.test(a.name)
  10. }
  11. })
  12. </script>
  13. <div ms-controller='test' >
  14. <div ms-for="(index,el) in @arr as items | filterBy(@fn)" >
  15. {{el.name}} -- {{items.length}}
  16. </div>
  17. </div>

selectBy

只能用于ms-for循环,只对对象有效, 用于抽取目标对象的几个值,构成新数组返回.

  • array,要抽取的属性名
  • defaults,如果目标对象不存在这个属性,那么从这个默认对象中得到默认值,否则为空字符串, 可选这个多用于表格, 每一列的对象可能存在属性顺序不一致或缺少的情况
  1. <script>
  2. avalon.define({
  3. $id: "selectBy",
  4. obj: {a: 'aaa', b: 'bbb', c: 'ccc', d: 'ddd', e: 'eee'},
  5. grid: [{a: 1, b: 2, c: 3}, {c: 11, b: 22, a: 33}, {b: 23, a: 44}],
  6. defaults: {
  7. a:'@@@',
  8. b:'$$$',
  9. c:'###'
  10. }
  11. })
  12. </script>
  13. <div ms-controller='selectBy'>
  14. <ul>
  15. <li ms-for='el in @obj | selectBy(["c","a","b"])'>{{el}}</li>
  16. </ul>
  17. <table border='1' width='200'>
  18. <tr ms-for="tr in @grid">
  19. <td ms-for="td in tr | selectBy(['a','b','c'],@defaults)">{{td}}</td>
  20. </tr>
  21. </table>
  22. </div>

事件过滤器

事件过滤器只要是对一些常用操作进行简化处理

对按键事件(keyup,keydown,keypress)到底按下了哪些功能键 或方向键进行友好的处理.许多人都记不清回车退格的keyCode是多少.对阻止默认行为与防止冒泡进行封装

esc

当用户按下esc键时,执行你的回调

tab

当用户按下tab键时,执行你的回调

enter

当用户按下enter键时,执行你的回调

space

当用户按下space键时,执行你的回调

del

当用户按下del键时,执行你的回调

up

当用户按下up键时,执行你的回调

down

当用户按下down键时,执行你的回调

left

当用户按下left键时,执行你的回调

right

当用户按下right键时,执行你的回调

prevent

阻止默为行为,多用于form的submit事件防止页面跳转,相当于调用了event.preventDefault

  1. <a href='./api.html' ms-click='@fn | prevent'>阻止跳转</a>

stop

阻止事件冒泡,相当于调用了event.stopPropagation

页面的过滤器只能用于事件绑定

同步频率过滤器

这两个过滤器只用于ms-duplex

change

在文本域或文本区使用ms-duplex时,默认是每输入一个字符就同步一次. 当我们想在失去焦点时才进行同步, 那么可以使用此过滤器

  1. <input ms-duplex='@aaa | change'>{{@aaa}}

debounce

当我们实现搜索框的自动完成时, 每输入一个字符可能就会向后台请求一次(请求关键字列表), 这样太频繁,后端撑不住,但使用change过滤器,则又太慢了.改为每隔几十毫秒请求一次就最好. 基于此常用需要开发出此过滤器. 拥有一个参数.

  • debounceTime: 数字, 不写默认是300,不能少于4,否则做无效处理
  1. <input ms-duplex='@aaa | debounce(200)'>

编写过滤器

编写一个过滤器是非常简单的. 目前用户可编写的过滤器有两种, 不带参数的及带参数.

比方说uppercase,就是不带参数

  1. vm.aaa = "aaa"
  2. <div>{{@aaa | uppercase}}</div>

输出:

  1. <div>AAA</div>

那它是怎么实现的呢? 源码是这样的

  1. avalon.filters.uppercase = function (str) {
  2. return String(str).toUpperCase()
  3. }

过滤器总是把它前方的表达式生成的东西作为过滤器的第一个参数,然后返回一个值

同理lowercase的源码也很简单. 之所以用String,因为我们总想返回一个字符串

  1. avalon.filters.lowercase = function (str) {
  2. return String(str).toLowerCase()
  3. }

那么我们自定义一个过滤器,就首先要看一下文档,注意不要与现有的过滤器同名. 比如我们定义一个haha的过滤器

  1. <script>
  2. avalon.filters.haha = function(a){
  3. return a +'haha'
  4. }
  5. avalon.define({
  6. $id:'test',
  7. aaa: '111'
  8. })
  9. </script>
  10. <div ms-controller='tesst'>{{@aaa | haha}}</div>// 111haha

我们再看带参数的,带参数的必须写的括号,把第二个,第三个,放到里面

  1. <div>{{@aaa | truncate(10,'...')}}</div>

truncate要传两个参数,那么看一下其源码是这样的:

  1. avalon.filters.truncate = function (str, length, truncation) {
  2. //length,新字符串长度,truncation,新字符串的结尾的字段,返回新字符串
  3. length = length || 30
  4. truncation = typeof truncation === "string" ? truncation : "..."
  5. return str.length > length ?
  6. str.slice(0, length - truncation.length) + truncation :
  7. String(str)
  8. }

好了,我们看一下如何写一个带参数的过滤器,里面重复利用已有的过滤器

众所周知,ms-attr是返回一个对象. 我们只想对其中的一个字段进行格式化.比如我们要处理title. 那么就起名为title.

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <script type="text/javascript" src="../dist/avalon.js"></script>
  6. <script>
  7. avalon.filters.title = function (obj, a, b) {
  8. var title = obj.title
  9. var newTitle = avalon.filters.truncate(title, a, b)
  10. obj.title = newTitle
  11. return obj
  12. }
  13. var vm = avalon.define({
  14. $id: 'test',
  15. el: '123456789qwert'
  16. })
  17. </script>
  18. </head>
  19. <body ms-controller="test">
  20. <div ms-attr="{title:@el} | title(10,'...')">333</div>
  21. </body>
  22. </html>