mirror of https://github.com/vuejs/vue.git
sd-model
This commit is contained in:
parent
1e90903da8
commit
b8781c54eb
1
TODO.md
1
TODO.md
|
|
@ -1,4 +1,3 @@
|
|||
- tests for sd-model, remove sd-value and sd-checked
|
||||
- add escape: {{{ things in here should not be parsed }}}
|
||||
- sd-transition
|
||||
- component examples
|
||||
|
|
|
|||
|
|
@ -537,6 +537,7 @@ CompilerProto.destroy = function () {
|
|||
utils.log('compiler destroyed: ', compiler.vm.$el)
|
||||
// unwatch
|
||||
compiler.observer.off()
|
||||
compiler.emitter.off()
|
||||
var i, key, dir, inss, binding,
|
||||
el = compiler.el,
|
||||
directives = compiler.dirs,
|
||||
|
|
|
|||
|
|
@ -8,15 +8,11 @@ module.exports = {
|
|||
},
|
||||
|
||||
text: function (value) {
|
||||
this.el.textContent = isValidTextValue(value)
|
||||
? value
|
||||
: ''
|
||||
this.el.textContent = toText(value)
|
||||
},
|
||||
|
||||
html: function (value) {
|
||||
this.el.innerHTML = isValidTextValue(value)
|
||||
? value
|
||||
: ''
|
||||
this.el.innerHTML = toText(value)
|
||||
},
|
||||
|
||||
style: {
|
||||
|
|
@ -57,38 +53,6 @@ module.exports = {
|
|||
}
|
||||
},
|
||||
|
||||
value: {
|
||||
bind: function () {
|
||||
var el = this.el, self = this
|
||||
this.change = function () {
|
||||
self.vm.$set(self.key, el.value)
|
||||
}
|
||||
el.addEventListener('keyup', this.change)
|
||||
},
|
||||
update: function (value) {
|
||||
this.el.value = value ? value : ''
|
||||
},
|
||||
unbind: function () {
|
||||
this.el.removeEventListener('keyup', this.change)
|
||||
}
|
||||
},
|
||||
|
||||
checked: {
|
||||
bind: function () {
|
||||
var el = this.el, self = this
|
||||
this.change = function () {
|
||||
self.vm.$set(self.key, el.checked)
|
||||
}
|
||||
el.addEventListener('change', this.change)
|
||||
},
|
||||
update: function (value) {
|
||||
this.el.checked = !!value
|
||||
},
|
||||
unbind: function () {
|
||||
this.el.removeEventListener('change', this.change)
|
||||
}
|
||||
},
|
||||
|
||||
model: {
|
||||
bind: function () {
|
||||
var self = this,
|
||||
|
|
@ -97,8 +61,8 @@ module.exports = {
|
|||
lazy = self.compiler.options.lazy
|
||||
self.event =
|
||||
(lazy ||
|
||||
el.tagName === 'SELECT' ||
|
||||
type === 'checkbox' ||
|
||||
type === 'select' ||
|
||||
type === 'radio')
|
||||
? 'change'
|
||||
: 'keyup'
|
||||
|
|
@ -111,11 +75,14 @@ module.exports = {
|
|||
el.addEventListener(self.event, self.set)
|
||||
},
|
||||
update: function (value) {
|
||||
this.el[this.attr] = this.attr === 'checked'
|
||||
? !!value
|
||||
: isValidTextValue(value)
|
||||
? value
|
||||
: ''
|
||||
if (this.el.type === 'radio') {
|
||||
/* jshint eqeqeq: false */
|
||||
this.el.checked = value == this.el.value
|
||||
} else {
|
||||
this.el[this.attr] = this.attr === 'checked'
|
||||
? !!value
|
||||
: toText(value)
|
||||
}
|
||||
},
|
||||
unbind: function () {
|
||||
this.el.removeEventListener(this.event, this.set)
|
||||
|
|
@ -167,6 +134,11 @@ function convertCSSProperty (prop) {
|
|||
})
|
||||
}
|
||||
|
||||
function isValidTextValue (value) {
|
||||
return typeof value === 'string' || typeof value === 'number'
|
||||
/*
|
||||
* Make sure only strings and numbers are output to html
|
||||
*/
|
||||
function toText (value) {
|
||||
return (typeof value === 'string' || typeof value === 'number')
|
||||
? value
|
||||
: ''
|
||||
}
|
||||
|
|
@ -213,89 +213,191 @@ describe('UNIT: Directives', function () {
|
|||
|
||||
})
|
||||
|
||||
describe('value', function () {
|
||||
describe('model', function () {
|
||||
|
||||
var dir = mockDirective('value', 'input')
|
||||
dir.bind()
|
||||
describe('input[checkbox]', function () {
|
||||
|
||||
var dir = mockDirective('model', 'input', 'checkbox')
|
||||
dir.bind()
|
||||
|
||||
before(function () {
|
||||
document.body.appendChild(dir.el)
|
||||
})
|
||||
|
||||
it('should set checked on update()', function () {
|
||||
dir.update(true)
|
||||
assert.ok(dir.el.checked)
|
||||
dir.update(false)
|
||||
assert.ok(!dir.el.checked)
|
||||
})
|
||||
|
||||
it('should trigger vm.$set when clicked', function () {
|
||||
var triggered = false
|
||||
dir.key = 'foo'
|
||||
dir.vm = { $set: function (key, val) {
|
||||
assert.strictEqual(key, 'foo')
|
||||
assert.strictEqual(val, true)
|
||||
triggered = true
|
||||
}}
|
||||
dir.el.dispatchEvent(mockMouseEvent('click'))
|
||||
assert.ok(triggered)
|
||||
})
|
||||
|
||||
it('should remove event listener with unbind()', function () {
|
||||
var removed = true
|
||||
dir.vm.$set = function () {
|
||||
removed = false
|
||||
}
|
||||
dir.unbind()
|
||||
dir.el.dispatchEvent(mockMouseEvent('click'))
|
||||
assert.ok(removed)
|
||||
})
|
||||
|
||||
after(function () {
|
||||
document.body.removeChild(dir.el)
|
||||
})
|
||||
|
||||
before(function () {
|
||||
document.body.appendChild(dir.el)
|
||||
})
|
||||
|
||||
it('should set the value on update()', function () {
|
||||
dir.update('foobar')
|
||||
assert.strictEqual(dir.el.value, 'foobar')
|
||||
describe('input[radio]', function () {
|
||||
|
||||
var dir1 = mockDirective('model', 'input', 'radio'),
|
||||
dir2 = mockDirective('model', 'input', 'radio')
|
||||
dir1.el.name = 'input-radio'
|
||||
dir2.el.name = 'input-radio'
|
||||
dir1.el.value = '12345'
|
||||
dir2.el.value = '54321'
|
||||
dir1.bind()
|
||||
dir2.bind()
|
||||
|
||||
before(function () {
|
||||
document.body.appendChild(dir1.el)
|
||||
document.body.appendChild(dir2.el)
|
||||
})
|
||||
|
||||
it('should set el.checked on update()', function () {
|
||||
assert.notOk(dir1.el.checked)
|
||||
dir1.update(12345)
|
||||
assert.ok(dir1.el.checked)
|
||||
})
|
||||
|
||||
it('should trigger vm.$set when clicked', function () {
|
||||
var triggered = false
|
||||
dir2.key = 'radio'
|
||||
dir2.vm = { $set: function (key, val) {
|
||||
triggered = true
|
||||
assert.strictEqual(key, 'radio')
|
||||
assert.strictEqual(val, dir2.el.value)
|
||||
}}
|
||||
dir2.el.dispatchEvent(mockMouseEvent('click'))
|
||||
assert.ok(triggered)
|
||||
assert.ok(dir2.el.checked)
|
||||
assert.notOk(dir1.el.checked)
|
||||
})
|
||||
|
||||
it('should remove listeners on unbind()', function () {
|
||||
var removed = true
|
||||
dir1.vm = { $set: function () {
|
||||
removed = false
|
||||
}}
|
||||
dir1.unbind()
|
||||
dir1.el.dispatchEvent(mockMouseEvent('click'))
|
||||
assert.ok(removed)
|
||||
})
|
||||
|
||||
after(function () {
|
||||
document.body.removeChild(dir1.el)
|
||||
document.body.removeChild(dir2.el)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
it('should trigger vm.$set when value is changed via keyup', function () {
|
||||
var triggered = false
|
||||
dir.key = 'foo'
|
||||
dir.vm = { $set: function (key, val) {
|
||||
assert.strictEqual(key, 'foo')
|
||||
assert.strictEqual(val, 'bar')
|
||||
triggered = true
|
||||
}}
|
||||
dir.el.value = 'bar'
|
||||
dir.el.dispatchEvent(mockKeyEvent('keyup'))
|
||||
assert.ok(triggered)
|
||||
describe('select', function () {
|
||||
|
||||
var dir = mockDirective('model', 'select')
|
||||
dir.el.innerHTML = '<option>0</option><option>1</option>'
|
||||
dir.bind()
|
||||
|
||||
before(function () {
|
||||
document.body.appendChild(dir.el)
|
||||
})
|
||||
|
||||
it('should set value on update()', function () {
|
||||
dir.update(0)
|
||||
assert.strictEqual(dir.el.value, '0')
|
||||
})
|
||||
|
||||
it('should trigger vm.$set when value is changed', function () {
|
||||
var triggered = false
|
||||
dir.key = 'select'
|
||||
dir.vm = { $set: function (key, val) {
|
||||
triggered = true
|
||||
assert.strictEqual(key, 'select')
|
||||
assert.equal(val, 1)
|
||||
}}
|
||||
dir.el.options.selectedIndex = 1
|
||||
dir.el.dispatchEvent(mockChangeEvent())
|
||||
assert.ok(triggered)
|
||||
})
|
||||
|
||||
it('should remove listener on unbind()', function () {
|
||||
var removed = true
|
||||
dir.vm = { $set: function () {
|
||||
removed = false
|
||||
}}
|
||||
dir.unbind()
|
||||
dir.el.dispatchEvent(mockChangeEvent())
|
||||
assert.ok(removed)
|
||||
})
|
||||
|
||||
after(function () {
|
||||
document.body.removeChild(dir.el)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
it('should remove event listener with unbind()', function () {
|
||||
var removed = true
|
||||
dir.vm.$set = function () {
|
||||
removed = false
|
||||
}
|
||||
dir.unbind()
|
||||
dir.el.dispatchEvent(mockKeyEvent('keyup'))
|
||||
assert.ok(removed)
|
||||
})
|
||||
describe('input[text] and others', function () {
|
||||
|
||||
after(function () {
|
||||
document.body.removeChild(dir.el)
|
||||
})
|
||||
var dir = mockDirective('model', 'input', 'email')
|
||||
dir.bind()
|
||||
|
||||
})
|
||||
before(function () {
|
||||
document.body.appendChild(dir.el)
|
||||
})
|
||||
|
||||
describe('checked', function () {
|
||||
it('should set the value on update()', function () {
|
||||
dir.update('foobar')
|
||||
assert.strictEqual(dir.el.value, 'foobar')
|
||||
})
|
||||
|
||||
var dir = mockDirective('checked', 'input', 'checkbox')
|
||||
dir.bind()
|
||||
// `lazy` option is tested in the API suite
|
||||
it('should trigger vm.$set when value is changed via keyup', function () {
|
||||
var triggered = false
|
||||
dir.key = 'foo'
|
||||
dir.vm = { $set: function (key, val) {
|
||||
assert.strictEqual(key, 'foo')
|
||||
assert.strictEqual(val, 'bar')
|
||||
triggered = true
|
||||
}}
|
||||
dir.el.value = 'bar'
|
||||
dir.el.dispatchEvent(mockKeyEvent('keyup'))
|
||||
assert.ok(triggered)
|
||||
})
|
||||
|
||||
before(function () {
|
||||
document.body.appendChild(dir.el)
|
||||
})
|
||||
it('should remove event listener with unbind()', function () {
|
||||
var removed = true
|
||||
dir.vm.$set = function () {
|
||||
removed = false
|
||||
}
|
||||
dir.unbind()
|
||||
dir.el.dispatchEvent(mockKeyEvent('keyup'))
|
||||
assert.ok(removed)
|
||||
})
|
||||
|
||||
it('should set checked on update()', function () {
|
||||
dir.update(true)
|
||||
assert.ok(dir.el.checked)
|
||||
dir.update(false)
|
||||
assert.ok(!dir.el.checked)
|
||||
})
|
||||
after(function () {
|
||||
document.body.removeChild(dir.el)
|
||||
})
|
||||
|
||||
it('should trigger vm.$set on change event', function () {
|
||||
var triggered = false
|
||||
dir.key = 'foo'
|
||||
dir.vm = { $set: function (key, val) {
|
||||
assert.strictEqual(key, 'foo')
|
||||
assert.strictEqual(val, true)
|
||||
triggered = true
|
||||
}}
|
||||
dir.el.dispatchEvent(mockMouseEvent('click'))
|
||||
assert.ok(triggered)
|
||||
})
|
||||
|
||||
it('should remove event listener with unbind()', function () {
|
||||
var removed = true
|
||||
dir.vm.$set = function () {
|
||||
removed = false
|
||||
}
|
||||
dir.unbind()
|
||||
dir.el.dispatchEvent(mockMouseEvent('click'))
|
||||
assert.ok(removed)
|
||||
})
|
||||
|
||||
after(function () {
|
||||
document.body.removeChild(dir.el)
|
||||
})
|
||||
|
||||
})
|
||||
|
|
@ -441,7 +543,7 @@ function mockDirective (dirName, tag, type) {
|
|||
var dir = Seed.directive(dirName),
|
||||
ret = {
|
||||
binding: { compiler: { vm: {} } },
|
||||
compiler: { vm: {} },
|
||||
compiler: { vm: {}, options: {} },
|
||||
el: document.createElement(tag || 'div')
|
||||
}
|
||||
if (typeof dir === 'function') {
|
||||
|
|
@ -455,6 +557,12 @@ function mockDirective (dirName, tag, type) {
|
|||
return ret
|
||||
}
|
||||
|
||||
function mockChangeEvent () {
|
||||
var e = document.createEvent('HTMLEvents')
|
||||
e.initEvent('change', true, true)
|
||||
return e
|
||||
}
|
||||
|
||||
function mockKeyEvent (type) {
|
||||
var e = document.createEvent('KeyboardEvent'),
|
||||
initMethod = e.initKeyboardEvent
|
||||
|
|
|
|||
Loading…
Reference in New Issue