Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix component update bug #103

Merged
merged 2 commits into from
Jul 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 20 additions & 16 deletions component.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,26 +52,30 @@ function afterUpdate (model, element, oldElement) {
}

Component.prototype.update = function (previous) {
var self = this

if (this.isViewComponent) {
var keys = Object.keys(this.model)
for (var n = 0; n < keys.length; n++) {
var key = keys[n]
previous.model[key] = self.model[key]
if (previous.key !== this.key || this.model.constructor !== previous.model.constructor) {
return this.init()
} else {
var self = this

if (this.isViewComponent) {
var keys = Object.keys(this.model)
for (var n = 0; n < keys.length; n++) {
var key = keys[n]
previous.model[key] = self.model[key]
}
this.model = previous.model
}
this.model = previous.model
}

this.component = previous.component
var oldElement = this.component.element
this.component = previous.component
var oldElement = this.component.element

var element = this.component.update(this.render(oldElement))
var element = this.component.update(this.render(oldElement))

if (self.model.detached) {
return document.createTextNode('')
} else {
return element
if (self.model.detached) {
return document.createTextNode('')
} else {
return element
}
}
}

Expand Down
6 changes: 0 additions & 6 deletions karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,6 @@ var browsers = {
os_version: 'El Capitan',
resolution: '1024x768'
},
'browserstack-safari-ios': {
base: 'BrowserStack',
device: 'iPhone 6S',
os: 'ios',
os_version: '9.1'
},
'browserstack-chrome': {
base: 'BrowserStack',
browser: 'Chrome',
Expand Down
5 changes: 4 additions & 1 deletion render.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
var simplePromise = require('./simplePromise')

function runRender (mount, fn) {
var render = new Render(mount)
if (runRender._currentRender) {
return
}

var render = new Render(mount)
try {
runRender._currentRender = render

Expand Down
136 changes: 134 additions & 2 deletions test/browser/hyperdomSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ describe('hyperdom', function () {
var self = this

return retry(function () {
expect(self.renderCount).to.equal(oldRefreshCount + 1)
expect(self.renderCount, 'renderCount').to.equal(oldRefreshCount + 1)
})
}
}
Expand Down Expand Up @@ -1537,6 +1537,122 @@ describe('hyperdom', function () {
})
})

it('calls onadd when a component of a different constructor rendered', function () {
var events = []
var monitor = renderMonitor()

function ComponentA () {
this.text = 'A'
}

ComponentA.prototype.onadd = function () {
events.push('onadd a')
}

ComponentA.prototype.render = function () {
return h('h1', this.text)
}

function ComponentB () {
this.text = 'B'
}

ComponentB.prototype.onadd = function () {
events.push('onadd b')
}

ComponentB.prototype.render = function () {
return h('h1', this.text)
}

var model = {
showComponentA: true,

render: function () {
monitor.rendering()

return h('div',
this.showComponentA ? new ComponentA() : new ComponentB(),
h('input.swap', {type: 'checkbox', binding: [this, 'showComponentA']})
)
}
}

attach(model)

expect(events).to.eql([
'onadd a'
])

return monitor.waitForRenderAfter(click('input.swap')).then(function () {
expect(events).to.eql([
'onadd a',
'onadd b'
])
return monitor.waitForRenderAfter(click('input.swap'))
}).then(function () {
expect(events).to.eql([
'onadd a',
'onadd b',
'onadd a'
])
return monitor.waitForRenderAfter(click('input.swap'))
})
})

it('calls onadd when a component of with a different key is rendered', function () {
var events = []
var monitor = renderMonitor()

function Component (key) {
this.debug = true
this.renderKey = key
this.text = key || 'a'
}

Component.prototype.onadd = function () {
events.push('onadd ' + this.text)
}

Component.prototype.render = function () {
return h('h1', this.text)
}

var model = {
showComponentA: true,

render: function () {
monitor.rendering()

return h('div',
new Component(this.showComponentA ? undefined : 'b'),
h('input.swap', {type: 'checkbox', binding: [this, 'showComponentA']})
)
}
}

attach(model)

expect(events).to.eql([
'onadd a'
])

return monitor.waitForRenderAfter(click('input.swap')).then(function () {
expect(events).to.eql([
'onadd a',
'onadd b'
])
return monitor.waitForRenderAfter(click('input.swap'))
}).then(function () {
expect(events).to.eql([
'onadd a',
'onadd b',
'onadd a'
])
return monitor.waitForRenderAfter(click('input.swap'))
})
})

describe('caching', function () {
it('can update the component only when the renderKey changes', function () {
var innerRenders = 0
Expand Down Expand Up @@ -1801,6 +1917,18 @@ describe('hyperdom', function () {
})
})
})

it('calling refreshImmediately inside a render does nothing', function () {
var model = {
render: function () {
this.refreshImmediately()
return h('h1', 'hi')
}
}

attach(model)
expect(find('h1').text()).to.equal('hi')
})
})

describe('hyperdom.binding', function () {
Expand Down Expand Up @@ -1838,6 +1966,10 @@ describe('hyperdom', function () {
}
})

afterEach(function () {
runRender._currentRender = undefined
})

function expectToRefresh (options, v) {
(hyperdom.refreshify(function () {}, options))()
expect(refreshCalled).to.equal(v)
Expand Down Expand Up @@ -2647,7 +2779,7 @@ describe('hyperdom', function () {
expect(find('button.activate').length).to.equal(1)
}).then(function () {
return click('div.click').then(function () {
wait(30).then(function () {
return wait(30).then(function () {
return retry(function () {
expect(find('div.clicks').text()).to.equal('1')
})
Expand Down