Skip to content

Commit

Permalink
* [jsfm] fix #1 #12
Browse files Browse the repository at this point in the history
  • Loading branch information
terrykingcha authored and Jinjiang committed Apr 20, 2016
1 parent d4fbadb commit 56e6a79
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 35 deletions.
15 changes: 14 additions & 1 deletion src/js-framework/lib/__test__/assets/subvm.input
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ define('@weex-component/subvm', function (require, exports, module) {
;
module.exports = {
data: function () {return {
item: {a: 'a', b: 'b'}
item: {a: 'a', b: 'b'},
className: 'fromOuter',
marginTop: 10
}}
}

Expand All @@ -53,6 +55,17 @@ define('@weex-component/subvm', function (require, exports, module) {
"children": [
{
"type": "innertpl",
"classList": function() {
return this.className
},
"style": {
marginTop: function() {
return this.marginTop
}
},
"events": {
"click": "clicked"
},
"attr": {
"outerData": function () {return this.item}
}
Expand Down
40 changes: 38 additions & 2 deletions src/js-framework/lib/vm/__test__/directive.js
Original file line number Diff line number Diff line change
Expand Up @@ -363,9 +363,22 @@ describe('bind external infomations to sub vm', () => {
'_bindSubVm', '_bindSubVmAfterInitialized']
beforeEach(() => {
vm = {
_data: {a: 1, b: 2},
_data: {a: 1, b: 2, c: 'class-style1'},
_watchers: [],
_app: {eventManager: {add: () => {}}}
_app: {eventManager: {add: () => {}}},
_options: {
style: {
'class-style1': {
aaa: 1,
bbb: 2
},
'class-style2': {
aaa: 2,
ccc: 3
}
}
},
foo: function () {}
}
extendVm(vm, methodNames)
subVm = {
Expand Down Expand Up @@ -414,6 +427,29 @@ describe('bind external infomations to sub vm', () => {
expect(subVm._rootEl.style.bbb).eql(3)
})

it('bind classlist to a sub vm with root element', () => {
subVm._rootEl = {
attr: {},
style: {},
event: []
}
const template = {
classList: function () {
return [this.c]
}
}
initElement(subVm._rootEl)
vm._bindSubVm(subVm, template)
vm._bindSubVmAfterInitialized(subVm, template)
expect(subVm._rootEl.classStyle.aaa).eql(1)
expect(subVm._rootEl.classStyle.bbb).eql(2)
vm.c = 'class-style2'
expect(subVm._rootEl.classStyle.aaa).eql(2)
expect(subVm._rootEl.classStyle.bbb).to.be.undefined
expect(subVm._rootEl.classStyle.ccc).eql(3)

})

it('bind events to a sub vm with root element', () => {
subVm._rootEl = {
attr: {},
Expand Down
87 changes: 55 additions & 32 deletions src/js-framework/lib/vm/directive.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,9 @@ export function _bindSubVm(subVm, template, repeatItem) {
}

export function _bindSubVmAfterInitialized(subVm, template) {
mergeClassStyle(template.classList, this, subVm)
mergeStyle(template.style, this, subVm)

// bind events
// todo: rebind if subVm._rootEl changed
if (subVm._rootEl) {
for (const key in (template.events || {})) {
const value = template.events[key]
this._setEvent(subVm._rootEl, key, value)
}
}
mergeEvent(template.events, this, subVm)
}

function mergeProps(target, props, vm, subVm) {
Expand All @@ -83,10 +76,10 @@ function mergeProps(target, props, vm, subVm) {
if (!props || props[key]) {
const value = target[key]
if (typeof value === 'function') {
vm._watch(value, function (v) {
const returnValue = vm._watch(value, function (v) {
subVm[key] = v
})
subVm[key] = value.bind(vm)()
subVm[key] = returnValue
}
else {
subVm[key] = value
Expand All @@ -99,12 +92,12 @@ function mergeStyle(target, vm, subVm) {
for (const key in target) {
const value = target[key]
if (typeof value === 'function') {
vm._watch(value, function (v) {
const returnValue = vm._watch(value, function (v) {
if (subVm._rootEl) {
subVm._rootEl.setStyle(key, v)
}
})
subVm._rootEl.setStyle(key, value.bind(vm)())
subVm._rootEl.setStyle(key, returnValue)
}
else {
if (subVm._rootEl) {
Expand All @@ -114,6 +107,34 @@ function mergeStyle(target, vm, subVm) {
}
}

function mergeClassStyle(target, vm, subVm) {
var css = vm._options && vm._options.style || {}

if (!subVm._rootEl) {
return
}

if (typeof target === 'function') {
const value = vm._watch(target, v => {
setClassStyle(subVm._rootEl, css, v)
})
setClassStyle(subVm._rootEl, css, value)
} else if (target) {
setClassStyle(subVm._rootEl, css, target)
}
}

function mergeEvent(target, vm, subVm) {
if (target && subVm._rootEl) {
for (const type in target) {
const handler = vm[target[type]]
if (handler) {
subVm._rootEl.addEvent(type, bind(handler, vm))
}
}
}
}

/**
* bind id to an element
* each id is unique in a whole vm
Expand Down Expand Up @@ -157,6 +178,21 @@ export function _setAttr(el, attr) {
this._bindDir(el, 'attr', attr)
}

function setClassStyle(el, css, classList) {
const classStyle = {}
const length = classList.length

for (let i = 0; i < length; i++) {
const style = css[classList[i]]
if (style) {
for (const key in style) {
classStyle[key] = style[key]
}
}
}
el.setClassStyle(classStyle)
}

/**
* bind classnames to an element
*/
Expand All @@ -170,28 +206,15 @@ export function _setClass(el, classList) {
return
}

const update = (classList) => {
const css = this._options.style
const classStyle = {}
const length = classList.length

for (let i = 0; i < length; i++) {
const style = css[classList[i]]
if (style) {
for (const key in style) {
classStyle[key] = style[key]
}
}
}
el.setClassStyle(classStyle)
}

const style = this._options && this._options.style || {}
if (typeof classList === 'function') {
this._watch(classList, update)
update(classList.call(this))
const value = this._watch(classList, v => {
setClassStyle(el, style, v)
})
setClassStyle(el, style, value)
}
else {
update(classList)
setClassStyle(el, style, classList)
}
}

Expand Down

0 comments on commit 56e6a79

Please sign in to comment.