Destroy view-models when destroying trees

This commit is contained in:
Thomas Nordquist
2019-05-07 13:18:02 +02:00
parent dfaae34cf5
commit 63f89d628e
7 changed files with 21 additions and 7 deletions

View File

@@ -97,7 +97,7 @@ class TreeNodeComponent extends React.Component<Props, State> {
treeNode.viewModel.change.subscribe(this.viewStateHasChanged) treeNode.viewModel.change.subscribe(this.viewStateHasChanged)
} }
private viewStateHasChanged = (msg: void) => { private viewStateHasChanged = () => {
this.props.treeNode.viewModel && this.setState({ selected: this.props.treeNode.viewModel.isSelected() }) this.props.treeNode.viewModel && this.setState({ selected: this.props.treeNode.viewModel.isSelected() })
} }

View File

@@ -1,6 +1,7 @@
import { Destroyable } from '../../../backend/src/Model/Destroyable'
import { EventDispatcher } from '../../../events' import { EventDispatcher } from '../../../events'
export class TopicViewModel { export class TopicViewModel implements Destroyable {
private selected: boolean private selected: boolean
public change = new EventDispatcher<void, TopicViewModel>() public change = new EventDispatcher<void, TopicViewModel>()
@@ -8,6 +9,10 @@ export class TopicViewModel {
this.selected = false this.selected = false
} }
public destroy() {
this.change.removeAllListeners()
}
public isSelected() { public isSelected() {
return this.selected return this.selected
} }

View File

@@ -0,0 +1,3 @@
export interface Destroyable {
destroy(): void
}

View File

@@ -1,7 +1,8 @@
import { Destroyable } from './Destroyable'
import { Hashable, TreeNode } from './' import { Hashable, TreeNode } from './'
const sha1 = require('sha1') const sha1 = require('sha1')
export class Edge<ViewModel> implements Hashable { export class Edge<ViewModel extends Destroyable> implements Hashable {
public name: string public name: string
public target!: TreeNode<ViewModel> public target!: TreeNode<ViewModel>

View File

@@ -1,4 +1,5 @@
import { ChangeBuffer } from './ChangeBuffer' import { ChangeBuffer } from './ChangeBuffer'
import { Destroyable } from './Destroyable'
import { import {
EventBusInterface, EventBusInterface,
EventDispatcher, EventDispatcher,
@@ -8,7 +9,7 @@ import {
import { TreeNode } from './' import { TreeNode } from './'
import { TreeNodeFactory } from './TreeNodeFactory' import { TreeNodeFactory } from './TreeNodeFactory'
export class Tree<ViewModel> extends TreeNode<ViewModel> { export class Tree<ViewModel extends Destroyable> extends TreeNode<ViewModel> {
public connectionId?: string public connectionId?: string
public updateSource?: EventBusInterface public updateSource?: EventBusInterface
public nodeFilter?: (node: TreeNode<ViewModel>) => boolean public nodeFilter?: (node: TreeNode<ViewModel>) => boolean

View File

@@ -1,7 +1,8 @@
import { Destroyable } from './Destroyable'
import { Edge, Message, RingBuffer } from './' import { Edge, Message, RingBuffer } from './'
import { EventDispatcher, MqttMessage } from '../../../events' import { EventDispatcher, MqttMessage } from '../../../events'
export class TreeNode<ViewModel> { export class TreeNode<ViewModel extends Destroyable> {
public sourceEdge?: Edge<ViewModel> public sourceEdge?: Edge<ViewModel>
public message?: Message public message?: Message
public mqttMessage?: MqttMessage public mqttMessage?: MqttMessage
@@ -103,6 +104,8 @@ export class TreeNode<ViewModel> {
for (const edge of this.edgeArray) { for (const edge of this.edgeArray) {
edge.target.destroy() edge.target.destroy()
} }
this.viewModel && this.viewModel.destroy()
this.viewModel = undefined
this.edgeArray = [] this.edgeArray = []
this.edges = {} this.edges = {}
this.cachedChildTopics = [] this.cachedChildTopics = []

View File

@@ -1,9 +1,10 @@
import { Base64Message } from './Base64Message' import { Base64Message } from './Base64Message'
import { Destroyable } from './Destroyable'
import { Edge, Tree, TreeNode } from './' import { Edge, Tree, TreeNode } from './'
export abstract class TreeNodeFactory { export abstract class TreeNodeFactory {
private static messageCounter = 0 private static messageCounter = 0
public static insertNodeAtPosition<ViewModel>(edgeNames: Array<string>, node: TreeNode<ViewModel>) { public static insertNodeAtPosition<ViewModel extends Destroyable>(edgeNames: Array<string>, node: TreeNode<ViewModel>) {
let currentNode: TreeNode<ViewModel> = new Tree() let currentNode: TreeNode<ViewModel> = new Tree()
let edge let edge
for (const edgeName of edgeNames) { for (const edgeName of edgeNames) {
@@ -16,7 +17,7 @@ export abstract class TreeNodeFactory {
node.sourceEdge!.target = node node.sourceEdge!.target = node
} }
public static fromEdgesAndValue<ViewModel>(edgeNames: Array<string>, value?: Base64Message | null): TreeNode<ViewModel> { public static fromEdgesAndValue<ViewModel extends Destroyable>(edgeNames: Array<string>, value?: Base64Message | null): TreeNode<ViewModel> {
const node = new TreeNode<ViewModel>() const node = new TreeNode<ViewModel>()
node.setMessage({ node.setMessage({
value: value || undefined, value: value || undefined,