用类与原型写一个组件(三)——学习笔记

  上一篇中,我们为组件添加了“删除一条item”的功能,现在,再增加一个“增加一条item”的功能。

  首先,在页面中增加一个按钮,用来触发添加功能(红框中的内容是对比上一篇新加的代码)。

  在main.js中绑定按钮的单击事件,触发add函数。

  再在smartList.js里写add函数。

 1   // 增加一条数据
 2   SmartList.prototype.add = function (data) {
 3 
 4     var isExist = false;
 5 
 6     // 判断id是否已存在
 7     $.each(this.list, function (i, val) {
 8       if (val.id === data.id) {
 9         isExist = true;
10         return false; // 退出循环
11       }
12     });
13 
14     if (isExist) {
15       console.log('SmartList: id ' + data.id + ' 已存在,无法添加');
16       return;
17     }
18 
19     this.list.push(data);
20     this._genItem(data).appendTo(this.element);
21   };

  现在可以注意到,$.each(this.list, function (i, val) {...}这行代码重复了,在add里用到了,在remove里也用到了,所以,我们是否可以写一个函数来代替这段重复的代码呢?于是,写一个_getById方法如下:

 1   SmartList.prototype._getById = function (id, callback) {
 2     var self = this;
 3     var data = null;
 4 
 5     $.each(this.list, function (i, val) {
 6       if (val.id === id) {
 7         data = val;
 8         if (callback && typeof callback === 'function')
 9           callback(i, data);
10         return false;
11       }
12     });
13 
14     return data;
15   };

  现在可以用_getById方法来改写remove和add方法。改写前后对比如下:

  完整代码如下:

index.html:

 1 <html>
 2 <head>
 3   <meta charset="UTF-8">
 4   <title>Flexx</title>
 5   <link href="http://apps.bdimg.com/libs/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet">
 6   <link rel="stylesheet" href="./css/main.css">
 7   <script src="http://apps.bdimg.com/libs/jquery/2.0.0/jquery.min.js"></script>
 8   <script src="http://apps.bdimg.com/libs/bootstrap/3.3.0/js/bootstrap.min.js"></script>
 9   <script src="./js/flexx.js"></script>
10   <script src="./js/smartList.js"></script>
11   <script src="./js/main.js"></script>
12 </head>
13 <body>
14   <div class="container">
15     <h1>Flexx Library</h1>
16     <hr>
17     <div class="row">
18       <div class="col-xs-6">
19         <div class="row">
20           <div class="col-xs-12">
21             <button id="btnAdd" class="btn btn-success">
22               &nbsp;<i class="glyphicon glyphicon-plus"></i>&nbsp;
23             </button>
24           </div>
25         </div>
26         <br>
27         <div id="memberList"></div>
28       </div>
29       <div class="col-xs-6">
30         <div id="groupList"></div>
31       </div>
32     </div>
33   </div>
34 </body>
35 </html>
View Code

smartList.js:

  1 /**
  2  * SmartList
  3  *
  4  * 数据源:id为必须项
  5  */
  6 
  7 + function (Flexx) {
  8   'use strict';
  9 
 10   // 定义一个SmartList类
 11   function SmartList(selector, options) {
 12 
 13     this.list = [];
 14 
 15     // 覆盖默认属性
 16     this.options = $.extend({
 17       // 默认属性
 18       isDeletable: true, // 设置是否有行删除按钮
 19       isEditable: true // 设置是否有行编辑按钮
 20     }, options);
 21 
 22     this.element = $(selector)
 23       .addClass('panel-group xx-smartlist');
 24 
 25     console.log('----创建了一个SmartList对象----');
 26   }
 27 
 28   // 更新列表
 29   SmartList.prototype.setData = function (list) {
 30     var self = this;
 31     // 更新list数据
 32     this.list = list;
 33     // 清空dom容器
 34     this.element.html('');
 35     // 渲染元素
 36     $.each(this.list, function (i, data) {
 37       self._genItem(data).appendTo(self.element);
 38     });
 39 
 40     console.log('-> setData done', this.element);
 41   };
 42 
 43   // 增加一条数据
 44   SmartList.prototype.add = function (data) {
 45     if(this._getById(data.id)){
 46       console.log('SmartList: id ' + data.id + ' 已存在,无法添加');
 47       return;
 48     }
 49     this.list.push(data);
 50     this._genItem(data).appendTo(this.element);   
 51   };
 52 
 53   SmartList.prototype.remove = function (id) {
 54     var self = this;
 55 
 56     this._getById(id, function (i, data) {
 57       self.list.splice(i, 1);
 58       self.element.find('[data-id="' + id + '"]').remove();
 59     });
 60   };
 61 
 62   SmartList.prototype._getById = function (id, callback) {
 63     var self = this;
 64     var data = null;
 65 
 66     $.each(this.list, function (i, val) {
 67       if (val.id === id) {
 68         data = val;
 69         if (callback && typeof callback === 'function')
 70           callback(i, data);
 71         return false;
 72       }
 73     });
 74 
 75     return data;
 76   };
 77 
 78   // 生成一个条目
 79   SmartList.prototype._genItem = function (data) {
 80     var self = this;
 81     var heading = 'heading_' + data.id;
 82     var collapse = 'collapse_' + data.id;
 83     var html = [
 84       '<div class="panel panel-default" data-id="' + data.id + '">',
 85       '<div class="panel-heading" role="tab" id="' + heading + '">',
 86       '<h4 class="panel-title">',
 87       '<a role="button" data-toggle="collapse" data-parent="#memberList" href="#' +
 88       collapse + '" aria-expanded="true" aria-controls="' + collapse + '">',
 89       data.title,
 90       '</a>',
 91       this.options.isDeletable ? '<i data-act="del" class="glyphicon glyphicon-remove pull-right"></i>' : '',
 92       this.options.isEditable ? '<i data-act="edit" class="glyphicon glyphicon-pencil pull-right"></i>' : '',
 93       '</h4>',
 94       '</div>',
 95       '<div id="' + collapse + '" class="panel-collapse collapse" role="tabpanel" aria-labelledby="' + heading + '">',
 96       '<div class="panel-body">',
 97       data.content,
 98       '</div>',
 99       '</div>',
100       '</div>'
101     ].join('');
102 
103     var item = $(html);
104 
105     if (this.options.isDeletable) {
106       item.find('[data-act="del"]').click(function () {
107         self.remove(data.id);
108       });
109     }
110 
111     return item;
112   };
113 
114   Flexx.SmartList = SmartList;
115 
116 }(window.xx = window.xx || {});
View Code

main.js:

 1 + function () {
 2   'use strict';
 3 
 4   // 创建一个用来测试的模拟数据
 5   var members = [{
 6     id: 0,
 7     title: 'Brandon',
 8     content: 'hello'
 9   }, {
10     id: 1,
11     title: 'Kim',
12     content: 'hi'
13   }, {
14     id: 2,
15     title: 'Bunny',
16     content: 'hi'
17   }, {
18     id: 3,
19     title: 'Lovelyun',
20     content: 'hi'
21   }];
22 
23   var groups = [{
24     id: 1,
25     title: 'Web Dev',
26     content: 'hello again'
27   }];
28 
29   $(function () {
30     // 初始化一个SmartList的实例对象
31     var memberList = new xx.SmartList('#memberList');
32     var groupList = new xx.SmartList('#groupList', {
33       isDeletable: false,
34       isEditable: false
35     });
36     // 调用原型方法更新数据
37     memberList.setData(members);
38     groupList.setData(groups);
39 
40     $('#btnAdd').click(function () {
41       memberList.add({
42         id: 4,
43         title: 'add',
44         content: 'hi'
45       });
46     });
47 
48   });
49 
50 }();
View Code

总结:

1、要尽量减少代码重复;

2、充分利用回调函数。

3、一个关于布尔值的知识点:

  任意javascript的值都可以转换为布尔值,下面的6个会转换为false:

undefined、null、0、-0、NaN、""//空字符串,其他值,包括对象(数组)都会转换成true。

posted @ 2016-01-05 12:07  lovelyun  阅读(682)  评论(0编辑  收藏  举报