Skip to content

Commit 2a4480e

Browse files
author
RubyLouvre
committed
处理内存泄露问题
1 parent 69016df commit 2a4480e

File tree

7 files changed

+63
-49
lines changed

7 files changed

+63
-49
lines changed

src/component/index.js

+26-25
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ avalon.directive('widget', {
7575
this.comVm = comVm
7676

7777
// ===创建组件的VM==END===
78-
var boss = avalon.scan(component.template, comVm)
79-
comVm.$render = boss
80-
replaceRoot(this, boss)
78+
var innerRender = avalon.scan(component.template, comVm)
79+
comVm.$render = innerRender
80+
replaceRoot(this, innerRender)
8181
var nodesWithSlot = []
8282
var directives = []
8383
if (this.fragment || component.soleSlot) {
@@ -87,11 +87,12 @@ avalon.directive('widget', {
8787
nodesWithSlot = this.root.children
8888
})
8989
directives = childBoss.directives
90+
this.childBoss= childBoss
9091
for (var i in childBoss) {
9192
delete childBoss[i]
9293
}
9394
}
94-
boss.directives.push.apply(boss.directives, directives)
95+
Array.prototype.push.apply(innerRender.directives, directives)
9596

9697
var arraySlot = [],
9798
objectSlot = {}
@@ -120,16 +121,16 @@ avalon.directive('widget', {
120121
}
121122
//将原来元素的所有孩子,全部移动新的元素的第一个slot的位置上
122123
if (component.soleSlot) {
123-
insertArraySlot(boss.vnodes, arraySlot)
124+
insertArraySlot(innerRender.vnodes, arraySlot)
124125
} else {
125-
insertObjectSlot(boss.vnodes, objectSlot)
126+
insertObjectSlot(innerRender.vnodes, objectSlot)
126127
}
127128
}
128129

129130
if (comment) {
130131
var dom = avalon.vdom(vdom, 'toDOM')
131132
comment.parentNode.replaceChild(dom, comment)
132-
comVm.$element = boss.root.dom = dom
133+
comVm.$element = innerRender.root.dom = dom
133134
delete this.reInit
134135
}
135136

@@ -141,24 +142,13 @@ avalon.directive('widget', {
141142
} else {
142143
fireComponentHook(comVm, vdom, 'Ready')
143144
}
144-
this.beforeDispose = function() {
145-
if (!this.cacheVm) {
146-
fireComponentHook(comVm, vdom, 'Dispose')
147-
comVm.$hashcode = false
148-
delete avalon.vmodels[comVm.$id]
149-
this.boss.dispose()
150-
} else {
151-
fireComponentHook(comVm, vdom, 'Leave')
152-
}
153-
154-
}
155-
156145
},
157146
diff: function(newVal, oldVal) {
158147
if (cssDiff.call(this, newVal, oldVal)) {
159148
return true
160149
}
161150
},
151+
162152
update: function(vdom, value) {
163153
this.oldValue = value //★★防止递归
164154
switch (this.readyState) {
@@ -187,18 +177,29 @@ avalon.directive('widget', {
187177
delete avalon.viewChanging
188178
break
189179
}
190-
}
180+
},
181+
beforeDispose: function() {
182+
var comVm = this.comVm
183+
if (!this.cacheVm) {
184+
fireComponentHook(comVm, this.node, 'Dispose')
185+
comVm.$hashcode = false
186+
delete avalon.vmodels[comVm.$id]
187+
this.innerRender && this.innerRender.dispose()
188+
} else {
189+
fireComponentHook(comVm, this.node, 'Leave')
190+
}
191+
},
191192
})
192193

193-
function replaceRoot(instance, boss) {
194-
instance.boss = boss
195-
var root = boss.root
194+
function replaceRoot(instance, innerRender) {
195+
instance.innerRender = innerRender
196+
var root = innerRender.root
196197
var vdom = instance.node
197198
for (var i in root) {
198199
vdom[i] = root[i]
199200
}
200-
boss.root = vdom
201-
boss.vnodes[0] = vdom
201+
innerRender.root = vdom
202+
innerRender.vnodes[0] = vdom
202203
}
203204

204205
function fireComponentHook(vm, vdom, name) {

src/directives/for.js

+12-7
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ avalon.directive('for', {
8686
})
8787
}
8888
delete this.updating
89+
},
90+
beforeDispose: function(){
91+
this.fragments.forEach(function(el){
92+
el.dispose
93+
})
8994
}
9095
})
9196

@@ -138,13 +143,13 @@ function diffList(instance) {
138143
var list = instance.preFragments
139144

140145
list.forEach(function(el) {
141-
el._destory = true
146+
el._dispose = true
142147
})
143148
instance.fragments.forEach(function(c, index) {
144149
var fragment = isInCache(cache, c.key)
145150
//取出之前的文档碎片
146151
if (fragment) {
147-
delete fragment._destory
152+
delete fragment._dispose
148153
fragment.oldIndex = fragment.index
149154
fragment.index = index // 相当于 c.index
150155
fragment.vm[instance.keyName] = instance.isArray ? index : fragment.key
@@ -164,7 +169,7 @@ function diffList(instance) {
164169

165170
fragment.vm[instance.valName] = val
166171
fragment.vm[instance.keyName] = instance.isArray ? index : fragment.key
167-
delete fragment._destory
172+
delete fragment._dispose
168173
} else {
169174
fragment = FragmentDecorator(c, instance, c.index)
170175
list.push(fragment)
@@ -186,10 +191,10 @@ function updateList(instance) {
186191
var list = instance.fragments
187192
var end = instance.end.dom
188193
for (var i = 0, item; item = list[i]; i++) {
189-
if (item._destory) {
194+
if (item._dispose) {
190195
list.splice(i, 1)
191196
i--
192-
item.destory()
197+
item.dispose()
193198
continue
194199
}
195200
if (item.oldIndex !== item.index) {
@@ -211,7 +216,7 @@ function updateList(instance) {
211216
* @param {type} fragment
212217
* @param {type} this
213218
* @param {type} index
214-
* @returns { key, val, index, oldIndex, this, dom, split, boss, vm}
219+
* @returns { key, val, index, oldIndex, this, dom, split, vm}
215220
*/
216221
function FragmentDecorator(fragment, instance, index) {
217222
var data = {}
@@ -235,7 +240,7 @@ function FragmentDecorator(fragment, instance, index) {
235240
})
236241
}
237242
fragment.index = index
238-
fragment.boss = avalon.scan(instance.fragment, vm, function() {
243+
fragment.innerRender = avalon.scan(instance.fragment, vm, function() {
239244
var oldRoot = this.root
240245
ap.push.apply(fragment.children, oldRoot.children)
241246
this.root = fragment

src/directives/html.js

+13-9
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,23 @@ import { avalon } from '../seed/core'
33
avalon.directive('html', {
44

55
update: function(vdom, value) {
6-
this.boss && this.boss.dispose()
7-
8-
this.boss = avalon.scan('<div class="ms-html-container">' + value + '</div>', this.vm, function() {
9-
10-
6+
this.beforeDispose()
7+
8+
this.innerRender = avalon.scan('<div class="ms-html-container">' + value + '</div>', this.vm, function() {
119
var oldRoot = this.root
12-
vdom.children.splice(0)
10+
if(vdom.children)
11+
vdom.children.splice(0)
1312
vdom.children = oldRoot.children
1413
this.root = vdom
15-
if(vdom.dom)
16-
avalon.clearHTML(vdom.dom)
14+
if (vdom.dom)
15+
avalon.clearHTML(vdom.dom)
1716
})
18-
17+
18+
},
19+
beforeDispose: function() {
20+
if (this.innerRender) {
21+
this.innerRender.dispose()
22+
}
1923
},
2024
delay: true
2125
})

src/directives/if.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ avalon.directive('if', {
99
delete props['ms-if']
1010
delete props[':if']
1111
this.fragment = avalon.vdom(this.node, 'toHTML')
12-
1312
},
1413
diff: function(newVal, oldVal) {
1514
var n = !!newVal
@@ -31,7 +30,7 @@ avalon.directive('if', {
3130
continueScan(this, vdom)
3231
p && p.replaceChild(vdom.dom, placeholder)
3332
} else { //移除DOM
34-
this.boss && this.boss.dispose()
33+
this.beforeDispose()
3534
vdom.nodeValue = 'if'
3635
vdom.nodeName = '#comment'
3736
delete vdom.children
@@ -42,11 +41,16 @@ avalon.directive('if', {
4241
p.replaceChild(placeholder, dom)
4342
}
4443
}
44+
},
45+
beforeDispose: function(){
46+
if (this.innerRender) {
47+
this.innerRender.dispose()
48+
}
4549
}
4650
})
4751

4852
function continueScan(instance, vdom) {
49-
var boss = instance.boss = avalon.scan(instance.fragment, instance.vm)
50-
avalon.shadowCopy(vdom, boss.root)
53+
var innerRender = instance.innerRender = avalon.scan(instance.fragment, instance.vm)
54+
avalon.shadowCopy(vdom, innerRender.root)
5155
delete vdom.nodeValue
5256
}

src/renders/domRender.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ class Render {
323323
for (var i = 0, el; el = list[i++];) {
324324
el.dispose()
325325
}
326-
//防止其他地方的this.boss && this.boss.dispose报错
326+
//防止其他地方的this.innerRender && this.innerRender.dispose报错
327327
for (var i in this) {
328328
if(i !== 'dispose')
329329
delete this[i]

src/vdom/VFragment.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ export class VFragment {
1919
this.split = f.lastChild
2020
return this.dom = f
2121
}
22-
destory() {
22+
dispose() {
2323
this.toFragment()
24-
this.boss && this.boss.dispose()
24+
this.innerRender && this.innerRender.dispose()
2525
for (var i in this) {
2626
this[i] = null
2727
}

src/vmodel/Action.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export class Action {
104104
endBatch('schedule ' + this.expr)
105105
}
106106
}
107-
removeDepends(filter) {
107+
removeDepends() {
108108
var self = this
109109
this.observers.forEach(function(depend) {
110110
avalon.Array.remove(depend.observers, self)

0 commit comments

Comments
 (0)