Upgrade to Pro — share decks privately, control downloads, hide ads and more …

KISSY.Base - all about that Base

KISSY.Base - all about that Base

KISSY.Base的设计方法和最佳实践

ningzbruc

August 06, 2015
Tweet

More Decks by ningzbruc

Other Decks in Programming

Transcript

  1. API var box = new Box({ content: 'this is a

    box!', parent: '#container', onShow: function() { alert('visible'); } }); box.show(); box.hide(); box.destroy(); # Example - Box
  2. -JGF$ZDMF ളଁᇛ௹ var box = new Box({ content: 'this is

    a box!', parent: '#container', onShow: function() { alert('visible'); } }); box.show(); box.hide(); box.destroy(); # Example - Box
  3. $POGJH ҕඔ஥ᇂ var box = new Box({ content: 'this is

    a box!', parent: '#container', onShow: function() { alert('visible'); } }); box.show(); box.hide(); box.destroy(); # Example - Box
  4. &WFOU ൙ࡱ๙ྐ var box = new Box({ content: 'this is

    a box!', parent: '#container', onShow: function() { alert('visible'); } }); box.show(); box.hide(); box.destroy(); # Example - Box
  5. /** * 构造函数 */ function Box() { this.init.apply(this, arguments); }

    /** * 原型 */ Box.prototype = { /** * 构造函数 */ constructor: Box, /** * 初始化 */ init: function() { /* ... */ }, /** * 销毁 */ destroy: function() { /* ... */ } }; -JGF$ZDMF ളଁᇛ௹ Step 1
  6. Step 1 /** * 初始化 */ init: function() { this.render();

    }, /** * 渲染 */ render: function() { this.box = document.createElement('div'); this.box.style.display = 'none'; this.box.innerHTML = this.cfg.content; this.cfg.parent.appendChild(this.box); }, /** * 销毁 */ destroy: function() { this.cfg.parent.removeChild(this.box); this.cfg = null; this.box = null; } -JGF$ZDMF ളଁᇛ௹
  7. /** * 初始化 */ init: function() { this.config(cfg); this.render(); },

    /** * 参数配置 */ config: function(cfg) { cfg = cfg || {}; cfg.parent = typeof cfg.parent == 'string' ? document.querySelector(cfg.parent) : cfg.parent; this.cfg = mix({ content: '', parent: document.body }, cfg); }, $POGJH ҕඔ஥ᇂ Step 2
  8. /** * 初始化 */ init: function() { this.config(cfg); this.render(); },

    /** * 参数配置 */ config: function(cfg) { cfg = cfg || {}; cfg.parent = typeof cfg.parent == 'string' ? document.querySelector(cfg.parent) : cfg.parent; this.cfg = mix({ content: '', parent: document.body }, cfg); }, Step 2 ਅݺ֥࡙ಸྟ
  9. /** * 展⽰示 */ show: function() { this.box.style.display = 'block';

    this.cfg.onShow && this.cfg.onShow.call(this); } Step 3 &WFOU ൙ࡱ๙ྐ
  10. /** * 初始化 */ init: function() { this.config(cfg); this.render(); },

    /** * 参数配置 */ config: function(cfg) { cfg = cfg || {}; cfg.parent = typeof cfg.parent == 'string' ? document.querySelector(cfg.parent) : cfg.parent; this.cfg = mix({ content: '', parent: document.body }, cfg); }, َ෫֥ҕඔ஥ᇂ Step 2
  11. buildParam : function(o) { var that = this; var o

    = ( typeof o == 'undefined' || o == null) ? {} : o; that.autoSlide = ( typeof o.autoSlide == 'undefined' || o.autoSlide == null) ? false : o.autoSlide; that.speed = ( typeof o.speed == 'undefined' || o.speed == null) ? 0.5 : o.speed; that.timeout = ( typeof o.timeout == 'undefined' || o.timeout == null) ? 1000 : o.timeout; that.timedelay = ( typeof o.timedelay == 'undefined' || o.timedelay == null) ? -1 : o.timedelay; that.effect = ( typeof o.effect == 'undefined' || o.effect == null) ? 'none' : o.effect; that.eventype = ( typeof o.eventype == 'undefined' || o.eventype == null) ? 'click' : o.eventype; that.easing = ( typeof o.easing == 'undefined' || o.easing == null) ? 'easeBoth' : o.easing; that.hoverStop = ( typeof o.hoverStop == 'undefined' || o.hoverStop == null) ? true : o.hoverStop; that.selectedClass = ( typeof o.selectedClass == 'undefined' || o.selectedClass == null) ? 'selected' : o.selectedClass; that.conClass = ( typeof o.conClass == 'undefined' || o.conClass == null) ? 't-slide' : o.conClass; that.navClass = ( typeof o.navClass == 'undefined' || o.navClass == null) ? 'tab-nav' : o.navClass; that.contentClass = ( typeof o.contentClass == 'undefined' || o.contentClass == null) ? 'tab-content' : o.contentClass; that.pannelClass = ( typeof o.pannelClass == 'undefined' || o.pannelClass == null) ? 'tab-pannel' : o.pannelClass; that.before_switch = ( typeof o.before_switch == 'undefined' || o.before_switch == null) ? new Function : o.before_switch; that.ready = ( typeof o.ready == 'undefined' || o.ready == null) ? new Function : o.ready; that.carousel = ( typeof o.carousel == 'undefined' || o.carousel == null) ? false : o.carousel; that.id = that.id; that.tabs = []; that.animcon = null; that.pannels = []; that.timer = null; that.defaultTab = ( typeof o.defaultTab == 'undefined' || o.defaultTab == null) ? 0 : Number(o.defaultTab) - 1; that.current_tab = that.defaultTab; return this; },
  12. buildParam : function(o) { var that = this; var o

    = ( typeof o == 'undefined' || o == null) ? {} : o; that.autoSlide = ( typeof o.autoSlide == 'undefined' || o.autoSlide == null) ? false : o.autoSlide; that.speed = ( typeof o.speed == 'undefined' || o.speed == null) ? 0.5 : o.speed; that.timeout = ( typeof o.timeout == 'undefined' || o.timeout == null) ? 1000 : o.timeout; that.timedelay = ( typeof o.timedelay == 'undefined' || o.timedelay == null) ? -1 : o.timedelay; that.effect = ( typeof o.effect == 'undefined' || o.effect == null) ? 'none' : o.effect; that.eventype = ( typeof o.eventype == 'undefined' || o.eventype == null) ? 'click' : o.eventype; that.easing = ( typeof o.easing == 'undefined' || o.easing == null) ? 'easeBoth' : o.easing; that.hoverStop = ( typeof o.hoverStop == 'undefined' || o.hoverStop == null) ? true : o.hoverStop; that.selectedClass = ( typeof o.selectedClass == 'undefined' || o.selectedClass == null) ? 'selected' : o.selectedClass; that.conClass = ( typeof o.conClass == 'undefined' || o.conClass == null) ? 't-slide' : o.conClass; that.navClass = ( typeof o.navClass == 'undefined' || o.navClass == null) ? 'tab-nav' : o.navClass; that.contentClass = ( typeof o.contentClass == 'undefined' || o.contentClass == null) ? 'tab-content' : o.contentClass; that.pannelClass = ( typeof o.pannelClass == 'undefined' || o.pannelClass == null) ? 'tab-pannel' : o.pannelClass; that.before_switch = ( typeof o.before_switch == 'undefined' || o.before_switch == null) ? new Function : o.before_switch; that.ready = ( typeof o.ready == 'undefined' || o.ready == null) ? new Function : o.ready; that.carousel = ( typeof o.carousel == 'undefined' || o.carousel == null) ? false : o.carousel; that.id = that.id; that.tabs = []; that.animcon = null; that.pannels = []; that.timer = null; that.defaultTab = ( typeof o.defaultTab == 'undefined' || o.defaultTab == null) ? 0 : Number(o.defaultTab) - 1; that.current_tab = that.defaultTab; return this; }, 85' 
  13. var box = new Box({ content: 'this is a box!',

    parent: '#container', onShow: function() { doA(); } }); /** * 展⽰示 */ show: function() { this.box.style.display = 'block'; this.cfg.onShow && this.cfg.onShow.call(this); } Step 3 &WFOU ൙ࡱ๙ྐ
  14. var box = new Box({ content: 'this is a box!',

    parent: '#container', onShow: function() { doA(); } }); /** * 展⽰示 */ show: function() { this.box.style.display = 'block'; this.cfg.onShow && this.cfg.onShow.call(this); } Step 3 &WFOU ൙ࡱ๙ྐ window.onload = loadFn; රᄻཌྷ്
  15. var box = new Box({ content: 'this is a box!',

    parent: '#container', onShow: function() { doA(); } }); /** * 展⽰示 */ show: function() { this.box.style.display = 'block'; this.cfg.onShow && this.cfg.onShow.call(this); } box.cfg.onShow = function() { doA(); doB(); }; Step 3 &WFOU ൙ࡱ๙ྐ window.onload = loadFn; රᄻཌྷ്
  16. var box = new Box({ content: 'this is a box!',

    parent: '#container', onShow: function() { doA(); } }); /** * 展⽰示 */ show: function() { this.box.style.display = 'block'; this.cfg.onShow && this.cfg.onShow.call(this); } var originOnShow = box.cfg.onShow; box.cfg.onShow = function() { originOnShow.apply(this, arguments); doB(); }; Step 3 &WFOU ൙ࡱ๙ྐ window.onload = loadFn; රᄻཌྷ്
  17. var box = new Box({ content: 'this is a box!',

    parent: '#container', onShow: function() { doA(); } }); /** * 展⽰示 */ show: function() { this.box.style.display = 'block'; this.cfg.onShow && this.cfg.onShow.call(this); } var originOnShow = box.cfg.onShow; box.cfg.onShow = function() { originOnShow.apply(this, arguments); doB(); }; Step 3 &WFOU ൙ࡱ๙ྐ ൙ࡱگႨ଴ window.onload = loadFn; රᄻཌྷ്
  18. Step 1 -JGF$ZDMF ളଁᇛ௹ // 继承Base var Box = Base.extend({

    /** * 初始化 */ initializer: function() { this.render(); }, /** * 渲染 */ render: function() { /* ... */ }, /** * 销毁 */ destructor: function() { this.cfg.parent.removeChild(this.box); this.cfg = null; this.box = null; } });
  19. Step 1 -JGF$ZDMF ളଁᇛ௹ // 继承Base var Box = Base.extend({

    /** * 初始化 */ initializer: function() { this.render(); }, /** * 渲染 */ render: function() { /* ... */ }, /** * 销毁 */ destructor: function() { this.cfg.parent.removeChild(this.box); this.cfg = null; this.box = null; } }); //初始化 var box = new Box({ /* ... */ }); //销毁 box.destroy();
  20. Step 1 -JGF$ZDMF ളଁᇛ௹ // 继承Base var Box = Base.extend({

    /** * 初始化 */ initializer: function() { this.render(); }, /** * 渲染 */ render: function() { /* ... */ }, /** * 销毁 */ destructor: function() { this.cfg.parent.removeChild(this.box); this.cfg = null; this.box = null; } }); //初始化 var box = new Box({ /* ... */ }); //销毁 box.destroy();
  21. Step 2 // 继承Base var Box = Base.extend({ /* ...

    */ }, { /** * 参数配置 */ ATTRS: { parent: { // 默认值 value: document.body, // 校验 validator: function(v) { return !!v; }, //获取 getter: function(v) { return v; }, //设置 setter: function(v) { return typeof v == 'string' ? document.querySelector(v) : v; } } } }); "UUSJCVUF ҕඔ஥ᇂ
  22. Step 2 // 继承Base var Box = Base.extend({ /* ...

    */ }, { /** * 参数配置 */ ATTRS: { parent: { // 默认值 value: document.body, // 校验 validator: function(v) { return !!v; }, //获取 getter: function(v) { return v; }, //设置 setter: function(v) { return typeof v == 'string' ? document.querySelector(v) : v; } } } }); "UUSJCVUF ҕඔ஥ᇂ var box = new Box({ parent: '#container', }); box.get('parent');
  23. Step 2 // 继承Base var Box = Base.extend({ /* ...

    */ }, { /** * 参数配置 */ ATTRS: { parent: { // 默认值 value: document.body, // 校验 validator: function(v) { return !!v; }, //获取 getter: function(v) { return v; }, //设置 setter: function(v) { return typeof v == 'string' ? document.querySelector(v) : v; } } } }); "UUSJCVUF ҕඔ஥ᇂ var box = new Box({ parent: '#container', }); box.get('parent');
  24. Step 2 // 继承Base var Box = Base.extend({ /* ...

    */ }, { /** * 参数配置 */ ATTRS: { parent: { // 默认值 value: document.body, // 校验 validator: function(v) { return !!v; }, //获取 getter: function(v) { return v; }, //设置 setter: function(v) { return typeof v == 'string' ? document.querySelector(v) : v; } } } }); "UUSJCVUF ҕඔ஥ᇂ var box = new Box({ parent: '#container', }); box.get('parent');
  25. Step 2 // 继承Base var Box = Base.extend({ /* ...

    */ }, { /** * 参数配置 */ ATTRS: { parent: { // 默认值 value: document.body, // 校验 validator: function(v) { return !!v; }, //获取 getter: function(v) { return v; }, //设置 setter: function(v) { return typeof v == 'string' ? document.querySelector(v) : v; } } } }); "UUSJCVUF ҕඔ஥ᇂ var box = new Box({ parent: '#container', }); box.get('parent');
  26. Step 2 // 继承Base var Box = Base.extend({ /* ...

    */ }, { /** * 参数配置 */ ATTRS: { parent: { // 默认值 value: document.body, // 校验 validator: function(v) { return !!v; }, //获取 getter: function(v) { return v; }, //设置 setter: function(v) { return typeof v == 'string' ? document.querySelector(v) : v; } } } }); "UUSJCVUF ҕඔ஥ᇂ var box = new Box({ parent: '#container', }); box.get('parent');
  27. Step 2 // 继承Base var Box = Base.extend({ /* ...

    */ }, { /** * 参数配置 */ ATTRS: { parent: { // 默认值 value: document.body, // 校验 validator: function(v) { return !!v; }, //获取 getter: function(v) { return v; }, //设置 setter: function(v) { return typeof v == 'string' ? document.querySelector(v) : v; } } } }); "UUSJCVUF ҕඔ஥ᇂ var box = new Box({ parent: '#container', }); box.get('parent');
  28. /** * 展⽰示 */ show: function() { this.box.style.display = 'block';

    this.fire('show'); } var box = new Box({ /* ... */ }); box.on('show', doA); box.on('show', doB); box.on('show', doC); Step 3 $VTUPN&WFOU ሱקၬ൙ࡱ
  29. /** * 展⽰示 */ show: function() { this.box.style.display = 'block';

    this.fire('show'); } var box = new Box({ /* ... */ }); box.on('show', doA); box.on('show', doB); box.on('show', doC); Step 3 $VTUPN&WFOU ሱקၬ൙ࡱ
  30. /** * 展⽰示 */ show: function() { this.box.style.display = 'block';

    this.fire('show'); } var box = new Box({ /* ... */ }); box.on('show', doA); box.on('show', doB); box.on('show', doC); Step 3 $VTUPN&WFOU ሱקၬ൙ࡱ window.onload = loadFn; window.addEventListener('load', loadFn, false); රᄻཌྷ്
  31. // 继承Base var Box = Base.extend({ /* ... */ },

    { /** * 参数配置 */ ATTRS: { /** * ⽗父节点 * @attribute parent * @type HTMLElement * @default document.body */ parent: { /* ... */ }, /** * 内容 * @attribute content * @type String */ content: { /* ... */ } /* ... */ } }); ၂ଢਔಖ ಸၞົ޹
  32. parent: { // 默认值 value: document.body, // 校验 validator: function(v)

    { return !!v; }, //获取 getter: function(v) { return v; }, //设置 setter: function(v) { return typeof v == 'string' ? document.querySelector(v) : v; } } parent: { // 默认值 value: document.body, //设置 setter: function(v) { if (!v) { return Attribute.INVALID; } return typeof v == 'string' ? document.querySelector(v) : v; } } ATTRS
  33. value vs. valueFn parent: { // 默认值 value: document.body, //设置

    setter: function(v) { if (!v) { return Attribute.INVALID; } return typeof v == 'string' ? document.querySelector(v) : v; } } parent: { // 默认值函数 valueFn: function() { return document.body; }, //设置 setter: function(v) { if (!v) { return Attribute.INVALID; } return typeof v == 'string' ? document.querySelector(v) : v; } } 防⽌止值未初始化
  34. value vs. valueFn data: { value: { a: 1, b:

    2 } } boxA.get('data').a = 2; boxB.get('data').a; // 2 data: { valueFn: function() { return { a: 1, b: 2 }; } } boxA.get('data').a = 2; boxB.get('data').a; // 1 防⽌止多实例间参数对象共同引⽤用
  35. on // DOM Event node.on('click', clickFn); node.on('click', clickFn, context); //

    Custom Event box.on('show', showFn); box.on('show', showFn, context);
  36. defaultFn /** * 初始化 */ initializer: function() { //发布事件 this.publish('show',

    { defaultFn: this._defShowFn }); }, /** * 展⽰示 */ show: function() { this.fire('show'); }, /** * 默认展⽰示回调 */ _defShowFn: function() { this.box.style.display = 'block'; } box.on('show', function(e) { console.log(e); }); box.fire('show');
  37. /** * 渲染事件 * @event render * @param {EventFacade} e

    事件对象 */ this.publish('render', { defaultTargetOnly: true }); /** * 清除查询字段(query)和结果(results)事件 * @event clear * @param {EventFacade} e 事件对象 * @preventable _defClearFn */ this.publish('clear', { defaultFn: this._defClearFn }); /** * 查询事件 * @event query * @param {EventFacade} e 事件对象 * @preventable _defQueryFn */ this.publish('query', { defaultFn: this._defQueryFn }); /** * 查询结果返回事件 * @event results * @param {EventFacade} e 事件对象 e.results * @preventable _defResultsFn */ this.publish('results', { defaultFn: this._defResultsFn }); we love defaultFns! NQJBVUPDPNQMFUFCBTFKT
  38. preventDefault /** * 初始化 */ initializer: function() { //发布事件 this.publish('show',

    { defaultFn: this._defShowFn }); }, /** * 展⽰示 */ show: function() { this.fire('show'); }, /** * 默认展⽰示回调 */ _defShowFn: function() { this.box.style.display = 'block'; } box.on('show', function(e) { e.preventDefault(); }); box.fire('show');
  39. bubbles //添加冒泡对象 box.addTarget(parent); box.on('show', function(e) { console.log('box'); }); parent.on('show', function(e)

    { console.log('parent'); }); box.fire('show'); /** * 初始化 */ initializer: function() { //发布事件 this.publish('show', { bubbles: true, // 默认为true defaultFn: this._defShowFn }); }, /** * 展⽰示 */ show: function() { this.fire('show'); }, /** * 默认展⽰示回调 */ _defShowFn: function() { this.box.style.display = 'block'; } વஞ
  40. stopImmediatePropagation box.on('show', function(e) { e.stopImmediatePropagation(); }); box.on('show', function(e) { console.log('box');

    }); parent.on('show', function(e) { console.log('parent'); }); box.fire('show'); ቅᆸવஞ x ቅᆸԮѬ x
  41. defaultTargetOnly /** * 初始化 */ initializer: function() { //发布事件 this.publish('render',

    { defaultFn: this._defRenderFn, defaultTargetOnly: true }); }, /** * 渲染 */ render: function() { this.fire('render'); }, /** * 默认渲染回调 */ _defRenderFn: function() { this.box = document.createElement('div'); this.get('parent').appendChild(this.box); } //添加冒泡对象 box.addTarget(parent); box.on('render', function(e) { console.log('box'); }); parent.on('render', function(e) { console.log('parent'); }); box.render(); વஞ ቅᆸଏಪྛູવஞ
  42. /** * 展⽰示 */ show: function() { this.fire('show'); }, /**

    * 默认展⽰示回调 */ _defShowFn: function() { this.box.style.display = 'block'; } box.show(); box.show(); box.show(); Y State? ીႵ஑؎֒భሑ෿
  43. /** * 展⽰示 */ show: function() { if (!this.visible) {

    this.fire('show'); this.visible = true; } }, /** * 默认展⽰示回调 */ _defShowFn: function() { this.box.style.display = 'block'; } box.show(); box.show(); box.show(); Y State ݖႿَ෫
  44. What we expect? /** * 展⽰示 */ show: function() {

    this.visible = true; }, /** * 默认展⽰示回调 */ _defShowFn: function() { this.box.style.display = 'block'; } box.show(); box.show(); box.show(); Y ሑ෿э߄આࠠэ߄
  45. attrChange /** * 初始化 */ initializer: function() { // 绑定状态变化回调

    this.on('afterVisibleChange', this._afterVisibleChange); }, /** * 展⽰示 */ show: function() { this.set('visible', true); }, /** * 隐藏 */ hide: function() { this.set('visible', false); }, /** * 默认展⽰示回调 */ _afterVisibleChange: function(e) { this.box.style.display = e.newVal ? 'block' : 'none'; }, box.show(); box.show(); box.show(); Y ሑ෿э߄આࠠэ߄
  46. attrChangeData box.on('afterVisibleChange', function(e) { e.src; // UI }); // 传⼊入额外参数

    box.set('visible', true, { data: { src: 'UI' } }); // 静默更新 box.set('visible', true, { silent: true }); x ҂Ԩؿ൙ࡱ
  47. extend /** * 继承 * @method extend * @param {Object}

    r ⼦子类 * @param {Object} s ⽗父类 * @param {Object} px 原型属性 * @param {Object} sx 静态属性 */ function extend(r, s, px, sx) { var sp = s.prototype, rp = Object.create(sp); rp.constructor = r; r.prototype = rp; r.superclass = sp; mix(rp, px); mix(r, sx); return r; } ࠿ӵჰ྘đ҂࠿ӵൌ২උྟ function SuperClass() { this.a = 1; } SuperClass.prototype.add = function() { console.log('add'); }; function SubClass() { this.b = 2; } SubClass.prototype.remove = function() { console.log('remove'); }; S.extend(SubClass, SuperClass, {}, {}); var sub = new SubClass(); sub instanceof SubClass; // true sub instanceof SuperClass; // true sub.add(); // add sub.remove(); // remove sub.b; // 2 sub.a; // undefined
  48. function SuperClass() { this.a = 1; } SuperClass.prototype.add = function()

    { console.log('add'); }; function SubClass() { SubClass.superclass.constructor.apply(this, arguments); // SuperClass.apply(this, arguments); 同上 this.b = 2; } SubClass.prototype.remove = function() { console.log('remove'); }; S.extend(SubClass, SuperClass, {}, {}); sub.b; // 2 sub.a; // 1 extend טႨڳো֥ܒᄯݦඔ Ԛ൓߄ൌ২උྟ
  49. extend & lifecycle function Box() { this.init.apply(this, arguments); } Box.prototype.init

    = function() { this.box = document.createElement('div'); document.body.appendChild(this.box); }; function Dialog() { Dialog.superclass.constructor.apply(this, arguments); } S.extend(Dialog, Box, { init: function() { this.box.innerHTML = 'this is a dialog'; } });
  50. extend & lifecycle function Box() { this.init.apply(this, arguments); } Box.prototype.init

    = function() { this.box = document.createElement('div'); document.body.appendChild(this.box); }; function Dialog() { Dialog.superclass.constructor.apply(this, arguments); } S.extend(Dialog, Box, { init: function() { this.box.innerHTML = 'this is a dialog'; } }); FSSPSUIJTCPYJTVOEFGJOFE ڭۂ
  51. extend & lifecycle function Box() { this.init.apply(this, arguments); } Box.prototype.init

    = function() { this.box = document.createElement('div'); document.body.appendChild(this.box); }; function Dialog() { Dialog.superclass.constructor.apply(this, arguments); } S.extend(Dialog, Box, { init: function() { Dialog.superclass.init.apply(this, arguments); this.box.innerHTML = 'this is a dialog'; } });
  52. extend & lifecycle function Box() { this.init.apply(this, arguments); } Box.prototype.init

    = function() { this.box = document.createElement('div'); document.body.appendChild(this.box); }; function Dialog() { Dialog.superclass.constructor.apply(this, arguments); } S.extend(Dialog, Box, { init: function() { Dialog.superclass.init.apply(this, arguments); this.box.innerHTML = 'this is a dialog'; } }); ԩ৘َ෫
  53. Base.extend // 继承Base var Box = Base.extend({ /** * 初始化

    */ initializer: function() { this.box = document.createElement('div'); document.body.appendChild(this.box); }, /** * 销毁 */ destructor: function() { this.box = null; } }); // 继承Box var Dialog = Box.extend({ /** * 初始化 */ initializer: function() { this.box.innerHTML = 'this is a dialog'; }, /** * 销毁 */ destructor: function() { this.box.innerHTML = ''; } }); // 1. Box: constructor // 2. Dialog: constructor // 3. Box: initializer // 4. Dialog: initializer var dialog = new Dialog(); // 5. Dialog: destructor // 6. Box: destructor dialog.destroy(); οඨ྽Ԛ൓߄აཧ߮
  54. Base.extend & ATTRS // 继承Base var Box = Base.extend({ /*

    ... */ }, { /** * 配置参数 */ ATTRS: { parent: { /* ... */ } } }); // 继承Box var Dialog = Box.extend({ /* ... */ }, { /** * 配置参数 */ ATTRS: { type: { /* ... */ } } }); var dialog = new Dialog({ parent: '#container', type: 'alert' }); dialog.get('parent'); // div#container dialog.get('type'); // alert ᆦӻކѩҕඔ஥ᇂ
  55. Extensions function Mask() { this.initMask(); } Mask.ATTRS = { opacity:

    { value: 0.5 } }; Mask.prototype.initMask = function() { this.mask = document.createElement('div'); this.mask.style.opacity = this.get('opacity'); this.get('parent').appendChild(this.mask); }; // 继承Box var Dialog = Box.extend([Mask], { /* ... */ }, { /* ... */ }); var dialog = new Dialog({ parent: '#container', type: 'alert', opacity: 0.8 }); dialog.mask; // div.mask dialog.get('opacity'); // 0.8 ࢳᯒଆॶđьႿົ޹
  56. KISSY.add(function(S, ACBase, ACList) { /** * ⾃自动完成组件(搜索联想) * @module autocomplete

    */ /** * ⾃自动完成组件 * @class AutoComplete * @extends AutoCompleteBase * @uses AutoCompleteList * @constructor */ var AutoComplete = ACBase.extend([ACList], {}, { name: 'AutoComplete' }); return AutoComplete; }, { requires: ['./base', './list', './index.css'] }); we love extensions! NQJBVUPDPNQMFUFJOEFYKT
  57. KISSY.add(function (S, Pad, Radio, Mask) { /** * 单选滑动组件 *

    @module slide-radio */ /** * 单选滑动组件 * @class SlideRadio * @extends Pad * @uses RadioExt * @uses MaskExt * @constructor */ var SlideRadio = Pad.extend([Radio.Ext, Mask.Ext], { /* ... */ }); return SlideRadio; }, { requires:['../pad/', '../radio/', '../mask/', './index.css'] }); we love extensions!
  58. What we expect function Mask() {} Mask.ATTRS = { opacity:

    { value: 0.5 } }; S.mix(Mask.prototype, { /** * 初始化 */ initializer: function() { this.mask = document.createElement('div'); this.mask.className = 'mask'; this.mask.style.opacity = this.get('opacity'); this.get('parent').appendChild(this.mask); }, /** * 销毁 */ destructor: function() { this.get('parent').removeChild(this.mask); } }); var Dialog = Box.extend([Mask], { /* ... */ }, { /* ... */ }); // 扩充额外的扩展 Dialog.mix(OtherExt); -JGF$ZDMF ളଁᇛ௹ ᆦӻحຓঔᅚ֥ঔԉ
  59. plugins var optimus = new Transformer(); // 初始化宿主环境 var gun

    = new Gun(); // 初始化插件 optimus.gun = gun; // 插⼊入插件 optimus.gun.fire(); // 调⽤用插件⽅方法 gun.destroy(); // 销毁插件 delete optimus.gun; // 拔出插件
  60. Base plugins function Gun() {} S.mix(Gun.prototype, { /** * 插件ID

    */ pluginId: 'Gun', /** * 插件初始化 */ pluginInitializer: function() {}, /** * 插件销毁 */ pluginDestructor: function() {}, /** * 开⽕火 */ fire: function() { } }); var optimus = new Transformer(); // 初始化宿主环境 optimus.plug(Gun); // 初始化并插⼊入插件 optimus.getPlugin('Gun').fire(); // 调⽤用插件⽅方法 optimus.unplug('Gun'); // 销毁插件
  61. What we expect var Gun = Plugin.extend({ pid: 'Gun', /**

    * 初始化 */ initializer: function() { console.log(this.get('host')); console.log(this.get('bullets')); }, /** * 初始化 */ destructor: function() { /* ... */ } }, { ATTRS: { bullets: { value: 1000 } } }); var optimus = new Transformer(); optimus.plug(Gun, { bullets: 2000 }); // optimus // 2000
  62. Extension vs. Plugin • 类级别 • 修改原型 • 必要的功能 •

    实例级别 • 不修改原型 • ⾮非必要的功能
  63. var Calendar = Pad.extend([Mask.Ext], { /** * 选中⽇日期节点 */ select:

    function(item) { this.fire('select', { item: item }); }, /** * 默认选中⽇日期节点 */ _defSelectFn: function(e) { this._selectedItem = e.item; this._selectedItem.addClass('selected'); } }); After Event var calendar = new Calendar(); calendar.on('select', function(e) { console.log(this._selectedItem); // null }); calendar.select(item); ೂޅᄝଏಪྛູᆭުԩ৘આࠠĤ
  64. var Calendar = Pad.extend([Mask.Ext], { /** * 选中⽇日期节点 */ select:

    function(item) { this.fire('select', { item: item }); }, /** * 默认选中⽇日期节点 */ _defSelectFn: function(e) { this._selectedItem = e.item; this._selectedItem.addClass('selected'); } }); What we expect োරႿBUUS$IBOHF ᄝଏಪྛູᆭުԩ৘આࠠ var calendar = new Calendar(); calendar.after('select', function(e) { console.log(this._selectedItem); // item }); calendar.select(item);
  65. AOP function Mask() {} Mask.prototype.renderMask = function() { this.mask =

    document.createElement('div'); this.get('parent').insertBefore(this.box, this.mask); }; var Box = Base.extend({ render: function() { this.box = document.createElement('div'); this.get('parent').appendChild(this.box); } }); var Dialog = Box.extend([Mask], {}); ೂޅᄝ҂ྩڿჰٚم֥భิ༯ ࡼSFOEFS.BTL٢֞SFOEFSުᆳྛĤ
  66. function Mask() { this.doAfter(this.renderMask, this, 'render', this); } Mask.prototype.renderMask =

    function() { this.mask = document.createElement('div'); this.get('parent').insertBefore(this.box, this.mask); }; var Box = Base.extend({ render: function() { this.box = document.createElement('div'); this.get('parent').appendChild(this.box); } }); var Dialog = Box.extend([Mask], {}); AOP SFOEFS.BTLࡼᄝSFOEFSުᆳྛ