avalon2
Version:
an elegant efficient express mvvm framework
1,229 lines (1,145 loc) • 38.4 kB
JavaScript
import { avalon } from '../../src/seed/core'
import '../../src/component/index'
avalon.component('ms-button', {
template: '<button type="button"><span><slot /></span></button>',
defaults: {
buttonText: "button"
},
soleSlot: 'buttonText'
})
avalon.component('ms-panel', {
template: heredoc(function() {
/*
<div>
<div class="body">
<slot name="body"></slot>
</div>
<p><ms-button :widget="@button" /></p>
</div>
*/
}),
defaults: {
body: " ",
button: {
buttonText: 'click me!'
}
},
soleSlot: 'body'
})
function getDiv(el) {
if (el.querySelector) {
return el.querySelector('.body')
} else {
var els = el.getElementsByTagName('div')
for (var i = 0, l = els.length; i < l; i++) {
if (els[i].className === 'body') {
return els[i]
}
}
}
}
describe('widget', function() {
var body = document.body,
div, vm
beforeEach(function() {
div = document.createElement('div')
body.appendChild(div)
})
afterEach(function() {
body.removeChild(div)
delete avalon.vmodels[vm.$id]
})
it('ms-button中buttonText', function(done) {
div.innerHTML = heredoc(function() {
/*
<div ms-controller='widget0' >
<xmp is='ms-button'>{{@btn}}</xmp>
<ms-button>这是标签里面的TEXT</ms-button>
<ms-button ms-widget='{buttonText:"这是属性中的TEXT"}'></ms-button>
<ms-button></ms-button>
</div>
*/
})
vm = avalon.define({
$id: 'widget0',
btn: '这是VM中的TEXT'
})
avalon.scan(div)
setTimeout(function() {
var span = div.getElementsByTagName('span')
expect(span[0][textProp]).toBe('这是VM中的TEXT')
expect(span[1][textProp]).toBe('这是标签里面的TEXT')
expect(span[2][textProp]).toBe('这是属性中的TEXT')
expect(span[3][textProp]).toBe('button')
vm.btn = '改动'
setTimeout(function() {
expect(span[0][textProp]).toBe('改动')
done()
})
})
})
it('通过更新配置对象修改组件界面(VM对象形式)', function(done) {
div.innerHTML = heredoc(function() {
/*
<div ms-controller='widget1' >
<xmp is='ms-panel' ms-widget="@aaa" style='border:1px solid red;display:block'>{{@aaa.panelBody}}</xmp>
</div>
*/
})
vm = avalon.define({
$id: 'widget1',
aaa: {
panelBody: 'aaa面板',
button: {
buttonText: "aaa按钮"
}
}
})
avalon.scan(div)
setTimeout(function() {
var div2 = getDiv(div)
var span = div.getElementsByTagName('span')[0]
expect(div2[textProp]).toBe('aaa面板')
expect(span[textProp]).toBe('aaa按钮')
vm.aaa.panelBody = '新面板'
vm.aaa.button.buttonText = "新按钮"
setTimeout(function() {
expect(div2[textProp]).toBe('新面板')
expect(span[textProp]).toBe('新按钮')
vm.aaa.panelBody = '新面板plus'
vm.aaa.button.buttonText = "新按钮plus"
setTimeout(function() {
expect(div2[textProp]).toBe('新面板plus')
expect(span[textProp]).toBe('新按钮plus')
done()
}, 300)
}, 300)
}, 300)
})
it('通过更新配置对象修改组件界面(数组形式)', function(done) {
div.innerHTML = heredoc(function() {
/*
<div ms-controller='widget1' >
<xmp ms-widget="[{is:'ms-panel'}, @aaa]" style='border:1px solid red;display:block'>{{@aaa.panelBody}}</xmp>
</div>
*/
})
vm = avalon.define({
$id: 'widget1',
aaa: {
panelBody: 'aaa面板',
button: {
buttonText: "aaa按钮"
}
}
})
avalon.scan(div)
setTimeout(function() {
var div2 = getDiv(div)
var span = div.getElementsByTagName('span')[0]
expect(div2[textProp]).toBe('aaa面板')
expect(span[textProp]).toBe('aaa按钮')
vm.aaa.panelBody = '新面板'
vm.aaa.button.buttonText = "新按钮"
setTimeout(function() {
expect(div2[textProp]).toBe('新面板')
expect(span[textProp]).toBe('新按钮')
vm.aaa.panelBody = '新面板plus'
vm.aaa.button.buttonText = "新按钮plus"
setTimeout(function() {
expect(div2[textProp]).toBe('新面板plus')
expect(span[textProp]).toBe('新按钮plus')
done()
}, 300)
}, 300)
}, 300)
})
it('通过更新配置对象修改组件界面(字面量形式)', function(done) {
div.innerHTML = heredoc(function() {
/*
<div ms-controller='widget1' >
<xmp is='ms-panel' ms-widget="{body: @aaa.panelBody, button: @aaa.button }" style='border:1px solid red;display:block'></xmp>
</div>
*/
})
vm = avalon.define({
$id: 'widget1',
aaa: {
panelBody: 'aaa面板',
button: {
buttonText: "aaa按钮"
}
}
})
avalon.scan(div)
setTimeout(function() {
var div2 = getDiv(div)
var span = div.getElementsByTagName('span')[0]
expect(div2[textProp]).toBe('aaa面板')
expect(span[textProp]).toBe('aaa按钮')
vm.aaa.panelBody = '新面板'
vm.aaa.button.buttonText = "新按钮"
setTimeout(function() {
expect(div2[textProp]).toBe('新面板')
expect(span[textProp]).toBe('新按钮')
vm.aaa.panelBody = '新面板plus'
vm.aaa.button.buttonText = "新按钮plus"
setTimeout(function() {
expect(div2[textProp]).toBe('新面板plus')
expect(span[textProp]).toBe('新按钮plus')
done()
}, 300)
}, 300)
}, 300)
})
it('确保都被扫描', function(done) {
div.innerHTML = heredoc(function() {
/*
<form ms-controller='widget2'>
<div ms-attr="{title:@option.text}">{{@option.text}}</div>
<ms-section ms-widget="@option"></ms-section>
</form>
*/
})
vm = avalon.define({
$id: 'widget2',
option: {
text: 'test'
}
});
avalon.component('ms-section', {
template: '<section><blockquote ms-attr="{title:@text}">{{@text}}</blockquote></section>',
defaults: {
text: 'default'
}
})
avalon.scan(div)
setTimeout(function() {
var div1 = div.getElementsByTagName('div')
expect(div1[0].innerHTML).toBe('test')
var blockquote1 = div.getElementsByTagName('blockquote')
expect(blockquote1[0].innerHTML).toBe('test')
expect(blockquote1[0].title).toBe('test')
vm.option.text = 999
setTimeout(function() {
expect(div1[0].innerHTML).toBe('999')
expect(blockquote1[0].innerHTML).toBe('999')
expect(blockquote1[0].title).toBe('999')
done()
})
})
});
it('确保生命周期钩子都生效,其onViewChange回调会在config被修复也触发', function(done) {
div.innerHTML = heredoc(function() {
/*
<form ms-controller='widget3'>
<wbr ms-widget="[{is:'ms-dialog',id:'aaa'},@config]" />
</form>
*/
})
var hookIndex = 0
avalon.component('ms-dialog', {
template: '<div class="dialog"><p><slot name="content"/></p></div>',
defaults: {
content: "内容",
onInit: function(a) {
hookIndex++
expect(a.type).toBe('init')
},
onReady: function(a) {
hookIndex++
expect(a.type).toBe('ready')
},
onViewChange: function(a) {
hookIndex++
expect(a.type).toBe('viewchange')
},
onDispose: function(a) {
hookIndex++
expect(a.type).toBe('dispose')
}
},
soleSlot: 'content'
})
vm = avalon.define({
$id: 'widget3',
config: {
content: '弹窗1'
}
})
avalon.scan(div, vm)
setTimeout(function() {
var divs = div.getElementsByTagName('div')
var successRender = false
for (var i = 0, el; el = divs[i++];) {
if (el.nodeType === 1 && el.className === 'dialog') {
successRender = true
break
}
}
expect(successRender).toBe(true)
var hasText = div.innerHTML.indexOf('弹窗1') > 0
expect(hasText).toBe(true)
vm.config.content = '弹窗2'
setTimeout(function() {
var hasText = div.innerHTML.indexOf('弹窗2') > 0
expect(hasText).toBe(true)
vm.$render.dispose()
//div.innerHTML = ''
setTimeout(function() {
expect(hookIndex).toBe(4)
done()
}, 120)
}, 120)
})
});
it('lifecycle', function(done) {
div.innerHTML = heredoc(function() {
/*
<div ms-controller='widget4' >
<div><wbr ms-widget="[{is:'ms-button'},@config]"/></div>
</div>
*/
})
var index = 0
vm = avalon.define({
$id: 'widget4',
config: {
buttonText: '按钮',
onInit: function(e) {
expect(e.type).toBe('init')
++index
},
onReady: function(e) {
expect(e.type).toBe('ready')
++index
},
onViewChange: function(e) {
expect(e.type).toBe('viewchange')
++index
},
onDispose: function(e) {
expect(e.type).toBe('dispose')
++index
}
}
})
avalon.scan(div)
setTimeout(function() {
expect(index + "!").toBe(2 + "!")
vm.config.buttonText = 'change'
setTimeout(function() {
vm.$render.dispose()
div.innerHTML = ""
setTimeout(function() {
expect(index).toBe(4)
done()
}, 120)
}, 120)
}, 120)
})
it('操作组件vm来更新组件的界面', function(done) {
div.innerHTML = heredoc(function() {
/*
<div ms-controller="widget5">
<xmp ms-widget='{is:"ms-pager"}'></xmp>
{{@bb}}
</div>
*/
})
vm = avalon.define({
$id: 'widget5',
bb: '其他内容'
});
avalon.component('ms-pager', {
template: '<div><strong>{{@totalPages}}</strong><button ms-click="@xx" type="button">++</button></div>',
defaults: {
totalPages: 21,
xx: function() {
this.totalPages += 1;
}
}
})
avalon.scan(div)
setTimeout(function() {
var button = div.getElementsByTagName('button')[0]
var strong = div.getElementsByTagName('strong')[0]
expect(strong.innerHTML).toBe('21')
fireClick(button)
expect(strong.innerHTML).toBe('22')
fireClick(button)
expect(strong.innerHTML).toBe('23')
fireClick(button)
expect(strong.innerHTML).toBe('24')
done()
})
})
it('使用顶层VM的子对象作配置对象', function(done) {
div.innerHTML = heredoc(function() {
/*
<div ms-controller='widget6' >
<wbr ms-widget="@config"/>
</div>
*/
})
var vm = avalon.define({
$id: 'widget6',
config: {
is: 'ms-button',
buttonText: '按钮',
onInit: function(a) {
console.log("onInit!!")
},
onReady: function(a) {
console.log("onReady!!")
},
onViewChange: function() {
console.log("onViewChange!!")
},
onDispose: function() {
console.log("onDispose!!")
}
}
})
avalon.scan(div, vm)
setTimeout(function() {
vm.config.buttonText = 'change'
setTimeout(function() {
var s = div.getElementsByTagName('span')[0]
expect(s[textProp]).toBe('change')
done()
}, 100)
}, 150)
})
it('组件的最外层元素定义其他指令不生效的BUG', function(done) {
div.innerHTML = heredoc(function() {
/*
<div ms-controller="widget7" id="widget7"><wbr ms-widget="[{is : 'Test'},@$config]"></div>
*/
})
avalon.component("Test", {
template: '<Test ms-attr="{title:@aaa}">{{##bbb}}</test>',
defaults: {
bbb: "TEST",
aaa: 'title'
}
})
vm = avalon.define({
$id: "widget7",
$config: {}
})
avalon.scan(div)
setTimeout(function() {
var widget = div.getElementsByTagName('test')[0]
expect(widget.nodeName.toLowerCase()).toBe('test')
expect(widget.title).toBe('title')
expect(widget.innerHTML).toBe('TEST')
delete avalon.components['Test']
done()
}, 150)
})
it(' 的解析问题', function(done) {
div.innerHTML = heredoc(function() {
/*
<div ms-controller="widget8">
<xmp cached='true' ms-widget="{is:'ms-time',id:'d234234'}"></xmp>
</div>
*/
})
avalon.component('ms-time', {
template: "<kbd ms-click='@click'>{{@aaa}} </kbd>",
defaults: {
aaa: 123
}
});
vm = avalon.define({
$id: "widget8"
})
avalon.scan(div)
setTimeout(function() {
var span = div.getElementsByTagName('kbd')[0]
expect(span.firstChild.nodeValue.trim()).toBe('123')
delete avalon.components['ms-time']
done()
}, 250)
})
it('应该ms-widget没有cached,并且出现不规范的ms-if的情况', function(done) {
//https://github.com/RubyLouvre/avalon/issues/1584
div.innerHTML = heredoc(function() {
/*
<div ms-controller="widget9"><wbr ms-widget="[{is:'ms-pagination2', id:'xxx_'}, @configPagination]"/></div>
*/
})
vm = avalon.define({
$id: 'widget9',
configPagination: {
totalPages: 0
},
clickPage1: function() {
vm.configPagination.totalPages = 0
},
clickPage2: function() {
vm.configPagination.totalPages = 12
}
})
var paginationTemplate = heredoc(function() {
/*
<nav ms-if="@_isShow">
{{@totalPages}}
</nav>
*/
});
avalon.component('ms-pagination2', {
template: paginationTemplate,
defaults: {
totalPages: 1,
_isShow: true,
isShowPagination: true,
onInit: function(e) {
var vm = e.vmodel;
vm._showPaginations();
this.$watch('totalPages', function(a) {
setTimeout(function() {
vm._showPaginations()
}, 2)
})
},
_showPaginations: function() {
var vm = this;
return vm._isShow = vm.totalPages > 0 && vm.isShowPagination
}
}
})
avalon.scan(div)
setTimeout(function() {
expect(div.getElementsByTagName('nav').length).toBe(0)
vm.clickPage2()
setTimeout(function() {
expect(div.getElementsByTagName('nav').length).toBe(1)
vm.clickPage1()
setTimeout(function() {
expect(div.getElementsByTagName('nav').length).toBe(0)
delete avalon.components['ms-pagination2']
delete avalon.vmodels.xxx_
done()
}, 150)
}, 150)
}, 150)
})
it('组件没有cached的情况不断切换里面的事件还能生效', function(done) {
div.innerHTML = heredoc(function() {
/*
<div ms-controller="widget10" ms-html="@tpl"></div>
*/
})
var v123 = heredoc(function() {
/*
<div ms-controller="widget10_1">
<p ms-click="@alert">123</p>
<wbr ms-widget="{is:'ms-remove',ddd: @ddd}"/>
</div>
*/
})
var v456 = heredoc(function() {
/*
<div ms-controller="widget10_2">
<p ms-click="@alert">456</p>
<wbr ms-widget="{is:'ms-remove',ddd: @ddd}"/>
</div>
*/
})
var clickIndex = 0
avalon.component('ms-remove', {
template: "<span ms-click='@click'>{{@ddd}}</span>",
defaults: {
ddd: '3333',
click: function() {
++clickIndex
}
}
});
vm = avalon.define({
$id: 'widget10',
tpl: v123,
switch1: function() {
vm.tpl = v123
},
switch2: function() {
vm.tpl = v456
}
})
avalon.define({
$id: 'widget10_1',
ddd: 'aaaa',
alert: function() {
avalon.log('????')
}
});
avalon.define({
$id: 'widget10_2',
ddd: 'bbbb',
alert: function() {
avalon.log('!!!!')
}
});
avalon.scan(div)
setTimeout(function() {
var spans = div.getElementsByTagName('span')
expect(spans.length).toBe(1)
expect(spans[0].innerHTML).toBe('aaaa')
vm.switch2()
setTimeout(function() {
var spans = div.getElementsByTagName('span')
expect(spans.length).toBe(1)
expect(spans[0].innerHTML).toBe('bbbb')
vm.switch1()
setTimeout(function() {
var spans = div.getElementsByTagName('span')
expect(spans.length).toBe(1)
expect(spans[0].innerHTML).toBe('aaaa')
fireClick(spans[0])
setTimeout(function() {
expect(clickIndex).toBe(1)
delete avalon.components['ms-remove']
delete avalon.vmodels['widget10_1']
delete avalon.vmodels['widget10_2']
done()
}, 20)
}, 100)
}, 100)
}, 150)
})
it('skipContent导致组件渲染异常', function(done) {
div.innerHTML = heredoc(function() {
/*
<div :controller="widget11">
<xmp :widget='{is:"CoursePlanCard", id:"CoursePlanCard"}'></xmp>
</div>
*/
})
avalon.component("CoursePlanCard", {
template: heredoc(function() {
/*
<div class="CoursePlanCard" >
<div class="CoursePlanCard-info">
<p class="CoursePlanCard-tip" id='aass'>
<span>计划类型:</span>{{''}}</p>
<p class="CoursePlanCard-tip">
<span>计划时间:</span>{{''}}</p>
<p class="CoursePlanCard-tip">
<span>必修学分:</span>{{''}}</p>
<p class="CoursePlanCard-tip">
<span>选修学分:</span>{{''}}</p>
</div>
</div>
*/
}),
defaults: {
onInit: function(a) {}
}
})
vm = avalon.define({
$id: "widget11"
})
avalon.scan(div)
setTimeout(function() {
expect(div.getElementsByTagName('span').length).toBe(4)
delete avalon.components['CoursePlanCard']
delete avalon.vmodels['widget11']
delete avalon.vmodels['CoursePlanCard']
done()
}, 150)
})
it('移动多个同名的slot元素到组件内部', function(done) {
div.innerHTML = heredoc(function() {
/*
<div :controller="widget12">
<xmp :widget='{is:"Slots"}'>
<p slot='aaa' >1111</p>
<p slot='aaa' >2222</p>
<p slot='bbb' >3333</p>
<p slot='bbb' >4444</p>
</xmp>
</div>
*/
})
avalon.component("Slots", {
template: heredoc(function() {
/*
<div class="slots" >
<div>
<slot name='aaa'/>
</div>
<div>
<slot name='bbb'/>
</div>
</div>
*/
}),
defaults: {
}
})
vm = avalon.define({
$id: "widget12",
arr: [1, 2, 3]
})
avalon.scan(div)
setTimeout(function() {
expect(div.getElementsByTagName('p').length).toBe(4)
delete avalon.components.Slots
done()
}, 150)
})
it('slot+ms-for', function(done) {
div.innerHTML = heredoc(function() {
/*
<div :controller="widget12">
<xmp :widget='{is:"Slots"}'>
<p slot='aaa' ms-for="el in @arr">{{el}}</p>
</xmp>
</div>
*/
})
avalon.component("Slots", {
template: heredoc(function() {
/*
<div class="slots" >
<div>
<slot name='aaa'/>
</div>
</div>
*/
}),
defaults: {
}
})
vm = avalon.define({
$id: "widget12",
arr: [111, 222, 333]
})
avalon.scan(div)
setTimeout(function() {
expect(div.getElementsByTagName('p').length).toBe(3)
delete avalon.components.Slots
done()
}, 150)
})
it('cached', function(done) {
div.innerHTML = heredoc(function() {
/*
<div ms-controller="widget13">
<div ms-if="@aaa">
<ms-button cached='true' ms-widget="{buttonText:Math.random(),id:'ddd' }"></ms-button>
</div>
</div>
*/
})
vm = avalon.define({
$id: 'widget13',
aaa: true
})
avalon.scan(div)
var button = div.getElementsByTagName('button')[0]
var text = button[textProp]
button.setAttribute('title', 'vvvv')
vm.aaa = false
setTimeout(function() {
vm.aaa = true
setTimeout(function() {
button = div.getElementsByTagName('button')[0]
expect(button[textProp]).toBe(text)
expect(button.getAttribute('title')).toBe('vvvv')
done()
}, 100)
}, 100)
})
it('路由组件', function(done) {
avalon.component('ms-hasha', {
template: '<div>{{@num}}<input type="text" ms-duplex-number="@num"/><button type="button" ms-on-click="@onPlus">+++</button></div>',
defaults: {
num: 1,
onPlus: function() {
this.num++;
}
}
});
var tpl = '<div><h4>{{@title}}</h4><button type="button" ms-on-click="@onChangeTitle">点击改变title</button></div>';
var time = 10
avalon.component('ms-hashb', {
template: tpl,
defaults: {
title: "这是标题",
random: 0,
onChangeTitle: function(e) {
this.title = 'title' + (++time);
}
}
});
vm = avalon.define({
$id: 'router',
panel: '',
hash: ''
})
function changePanel(v) {
vm.panel = '<' + v + ' cached="true" ms-widget="{id:\'' + v + '\'}"></' + v + '>'
}
vm.$watch('hash', changePanel)
vm.hash = 'ms-hasha'
div.innerHTML = heredoc(function() {
/*
<div ms-controller="router" ms-html="@panel">xxx</div>
*/
})
avalon.scan(div)
setTimeout(function() {
var input = div.getElementsByTagName('input')[0]
var button = div.getElementsByTagName('button')[0]
expect(input.value).toBe('1')
fireClick(button)
expect(input.value).toBe('2')
fireClick(button)
expect(input.value).toBe('3')
fireClick(button)
expect(input.value).toBe('4')
vm.hash = 'ms-hashb'
setTimeout(function() {
var h4 = div.getElementsByTagName('h4')[0]
var button = div.getElementsByTagName('button')[0]
expect(h4.innerHTML).toBe('这是标题')
fireClick(button)
expect(h4.innerHTML).toBe('title11')
fireClick(button)
expect(h4.innerHTML).toBe('title12')
fireClick(button)
expect(h4.innerHTML).toBe('title13')
vm.hash = 'ms-hasha'
setTimeout(function() {
var input = div.getElementsByTagName('input')[0]
var button = div.getElementsByTagName('button')[0]
expect(input.value).toBe('4')
fireClick(button)
expect(input.value).toBe('5')
fireClick(button)
expect(input.value).toBe('6')
fireClick(button)
expect(input.value).toBe('7')
done()
})
})
})
})
it('延迟初始化组件', function(done) {
if (avalon.msie < 9) {
div.innerHTML = heredoc(function() {
/*
<div ms-controller="widget14" style="behavior: url(#default#VML)" ><v:ms-kkk/></div>
*/
})
} else {
div.innerHTML = heredoc(function() {
/*
<div ms-controller="widget14" ><ms-kkk /></div>
*/
})
}
console.log(div.innerHTML, '延迟初始化')
vm = avalon.define({
$id: 'widget14'
})
avalon.scan(div)
setTimeout(function() {
expect(div.innerHTML).toMatch(/unresolved/)
avalon.component('ms-kkk', {
template: '<div>good</div>',
defaults: {}
})
setTimeout(function() {
expect(div.innerHTML).toMatch(/good/)
done()
delete avalon.components['ms-kkk']
}, 100)
}, 100)
})
it('object slot', function(done) {
div.innerHTML = heredoc(function() {
/*
<div ms-controller="widget15">
<ms-myview>
<div slot="header">aaa</div>
<div slot="body">bbb</div>
</ms-myview>
</div>
*/
})
avalon.component('ms-myview', {
template: '<div type="button">\
<slot name="header" />\
<slot name="body" />\
</div>',
defaults: {
buttonText: ""
}
})
vm = avalon.define({
$id: 'widget15'
});
avalon.scan(div)
setTimeout(function() {
expect(div[textProp].replace(/[\r\n\s]+/g, '')).toBe('aaabbb')
done()
delete avalon.components['ms-myview']
}, 100)
})
it('onViewChange', function(done) {
var onViewChangeCount = 0
avalon.component('ms-select', {
template: heredoc(function() {
/*
<div>
<select ms-duplex="@num">
<option ms-for="el in @numList">{{el}}</option>
</select>
<p>{{@num}}</p>
</div>
*/
}),
defaults: {
numList: [6, 12, 18, 24, 30],
num: 12,
onInit: function() {
console.log('onInit')
},
onReady: function() {
console.log('onReady')
},
onViewChange: function(e) {
++onViewChangeCount
}
}
})
div.innerHTML = heredoc(function() {
/*
<div ms-controller="widget16" ><ms-select :widget="{num: @aaa}" /></div>
*/
})
vm = avalon.define({
$id: 'widget16',
aaa: 6
})
avalon.scan(div)
setTimeout(function() {
var p = div.getElementsByTagName('p')[0]
expect(p.innerHTML).toBe('6')
vm.aaa = 12
setTimeout(function() {
expect(p.innerHTML).toBe('12')
vm.aaa = 18
setTimeout(function() {
expect(p.innerHTML).toBe('18')
setTimeout(function() {
expect(onViewChangeCount).toBe(2)
delete avalon.components['ms-select']
done()
}, 100)
}, 100)
}, 100)
}, 300)
})
it('根节点出现ms-if=false', function(done) {
div.innerHTML = heredoc(function() {
/*
<div ms-controller='widget17'>
<wbr is="ms-iff1" ms-widget='{aaa: 111, toggle: true}'/>
<wbr is="ms-iff1" ms-widget='{aaa: 222, toggle: false}'/>
</div>
*/
})
avalon.component('ms-iff1', {
template: '<p ms-if="@toggle" ms-text="@aaa"></p>',
defaults: {
toggle: true,
aaa: 333
}
})
vm = avalon.define({
$id: 'widget17'
})
avalon.scan(div, vm)
setTimeout(function() {
expect(div[textProp]).toBe('111')
done()
}, 100)
})
it('avalon2.2.2 组件只传递数组多次更新只有第一次可以更新到组件', function(done) {
//https://github.com/RubyLouvre/avalon/issues/1856
div.innerHTML = heredoc(function() {
/*
<div ms-controller='widget18'>
<xmp ms-widget="{is:'vip-test', id:'vip',data:@data}"></xmp>
</div>
*/
})
avalon.component('vip-test', {
template: '<p><span ms-for="(index,value) in @data">{{value}}|</span></p>',
defaults: {
data: [],
obj: {}
}
})
vm = avalon.define({
$id: 'widget18',
data: []
})
avalon.scan(div, vm)
setTimeout(function() {
vm.data = [1, 2, 3, 4, 5, 6]
setTimeout(function() {
vm.data.pushArray([7, 8])
setTimeout(function() {
vm.data.pushArray([100, 200])
expect(div[textProp]).toBe('1|2|3|4|5|6|7|8|100|200|')
delete avalon.components['vip-test']
done()
}, 100)
}, 100)
}, 100)
})
it('处理数组', function(done) {
avalon.component("ms-pager2", {
template: heredoc(function() {
/*
<div class="pagination">
<ul>
<li :for="el in @pages"
:class="[ el == @currentPage && 'active' ]">
<a href="javascript:void(0)" :click="@gotoPage(el, $event)">{{el}}</a>
</li>
</ul>
</div>
*/
}),
defaults: {
totalPage: 25,
currentPage: 1,
showPage: 5,
pages: [1, 2, 3, 4, 5],
gotoPage: function(page, e) {
this.currentPage = page;
this.pages = this.getPages();
},
getPages: function() {
var pages = [];
var s = this.showPage,
l = this.currentPage,
r = this.currentPage,
c = this.totalPage;
pages.push(l);
while (true) {
if (pages.length >= s) {
break;
}
if (l > 1) {
pages.unshift(--l);
}
if (pages.length >= s) {
break;
}
if (r < c) {
pages.push(++r);
}
}
return pages;
}
}
});
div.innerHTML = heredoc(function() {
/*
<div ms-controller="widget19">
<wbr is="ms-pager2" />
<style>
.pagination ul{
list-style: none;
margin: 0;
padding: 0;
}
.pagination li{
float: left;
}
.pagination li a{
text-decoration: none;
display: inline-block;
width:40px;
height: 30px;
line-height: 30px;
text-align: center;
background: #fafafa;
color:#000;
}
.pagination .active a{
background: #009a61;
color:#fff;
}
</style>
</div>
*/
})
vm = avalon.define({
$id: 'widget19'
})
avalon.scan(div)
setTimeout(function() {
var ul = div.getElementsByTagName('ul')[0]
expect(ul[textProp]).toBe('12345')
var lis = ul.getElementsByTagName('a')
fireClick(lis[3])
setTimeout(function() {
expect(ul[textProp]).toBe('23456')
fireClick(lis[3])
setTimeout(function() {
expect(ul[textProp]).toBe('34567')
fireClick(lis[0])
setTimeout(function() {
expect(ul[textProp]).toBe('12345')
delete avalon.components['ms-pager2']
done()
}, 120)
}, 120)
}, 120)
}, 100)
})
//有空加上这个测试 https://github.com/RubyLouvre/avalon/issues/1862
it("修正selected同步BUG", function(done){
div.innerHTML = heredoc(function(){
/*
<div ms-controller="widget20">
<div class="panel panel-default ms-controller" >
<xmp ms-widget="{is:'ms-pager3'}"></xmp>
</div>
</div>
*/
})
avalon.component('ms-pager3', {
template: heredoc(function(){
/*
<select ms-duplex="@countPerPage">
<option role="option" value="5">5</option>
<option role="option" value="10">10</option>
<option role="option" value="20">20</option></select>
*/
}),
defaults: {
countPerPage: 10
}
});
vm = avalon.define({
$id: 'widget20'
})
avalon.scan(div, vm)
setTimeout(function(){
var op = div.getElementsByTagName('option')
expect(op[1].selected).toBe(true)
delete avalon.components['ms-pager3']
done()
})
})
})