neo.mjs 8.4.2 → 8.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='8.4.2'
23
+ * @member {String} version='8.6.0'
24
24
  */
25
- version: '8.4.2'
25
+ version: '8.6.0'
26
26
  }
27
27
 
28
28
  /**
@@ -16,7 +16,7 @@
16
16
  "@type": "Organization",
17
17
  "name": "Neo.mjs"
18
18
  },
19
- "datePublished": "2025-01-14",
19
+ "datePublished": "2025-01-21",
20
20
  "publisher": {
21
21
  "@type": "Organization",
22
22
  "name": "Neo.mjs"
@@ -107,7 +107,7 @@ class FooterContainer extends Container {
107
107
  }, {
108
108
  module: Component,
109
109
  cls : ['neo-version'],
110
- html : 'v8.4.2'
110
+ html : 'v8.6.0'
111
111
  }]
112
112
  }],
113
113
  /**
@@ -84,18 +84,6 @@ class ContentComponent extends Component {
84
84
 
85
85
  if (value) {
86
86
  me.timeout(50).then(() => {
87
- me.customComponents.forEach(component => {
88
- if (!component.mounted && !component.rendering) {
89
- component.render(true)
90
- }
91
- });
92
-
93
- me.livePreviews.forEach(livePreview => {
94
- if (!livePreview.mounted && !livePreview.rendering) {
95
- livePreview.render(true)
96
- }
97
- });
98
-
99
87
  Neo.main.addon.IntersectionObserver.register({
100
88
  callback: 'findTopmostItem',
101
89
  id : me.id,
@@ -110,7 +98,7 @@ class ContentComponent extends Component {
110
98
 
111
99
  me.livePreviews.forEach(livePreview => {
112
100
  livePreview.mounted = false
113
- });
101
+ })
114
102
  }
115
103
  }
116
104
 
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='8.4.2'
23
+ * @member {String} version='8.6.0'
24
24
  */
25
- version: '8.4.2'
25
+ version: '8.6.0'
26
26
  }
27
27
 
28
28
  /**
@@ -27,67 +27,21 @@ class MainStore extends Store {
27
27
  }
28
28
 
29
29
  firstnames = [
30
- 'Ashley',
31
- 'Barbara',
32
- 'Betty',
33
- 'Chris',
34
- 'David',
35
- 'Elizabeth',
36
- 'Jack',
37
- 'James',
38
- 'Jennifer',
39
- 'Jessica',
40
- 'Joe',
41
- 'John',
42
- 'Karen',
43
- 'Kelly',
44
- 'Kim',
45
- 'Linda',
46
- 'Lisa',
47
- 'Mary',
48
- 'Max',
49
- 'Michael',
50
- 'Nancy',
51
- 'Patricia',
52
- 'Rich',
53
- 'Robert',
54
- 'Sam',
55
- 'Sandra',
56
- 'Sarah',
57
- 'Susan',
58
- 'Thomas',
59
- 'Tobias'
30
+ 'Amanda', 'Andrew', 'Anthony', 'Ashley', 'Barbara', 'Betty', 'Brian', 'Carol', 'Charles', 'Christopher',
31
+ 'Daniel', 'David', 'Deborah', 'Donna', 'Elizabeth', 'Emily', 'George', 'Jack', 'James', 'Jennifer',
32
+ 'Jessica', 'Joe', 'John', 'Joseph', 'Joshua', 'Karen', 'Kenneth', 'Kelly', 'Kevin', 'Kimberly',
33
+ 'Linda', 'Lisa', 'Margaret', 'Mark', 'Mary', 'Matthew', 'Max', 'Melissa', 'Michael', 'Michelle',
34
+ 'Nancy', 'Patricia', 'Paul', 'Richard', 'Robert', 'Ronald', 'Sam', 'Sandra', 'Sarah', 'Stephanie',
35
+ 'Steven', 'Susan', 'Thomas', 'Timothy', 'Tobias', 'William'
60
36
  ]
61
37
 
62
38
  lastnames = [
63
- 'Anderson',
64
- 'Brown',
65
- 'Davis',
66
- 'Garcia',
67
- 'Gonzales',
68
- 'Harris',
69
- 'Hernandez',
70
- 'Jackson',
71
- 'Johnson',
72
- 'Jones',
73
- 'Lee',
74
- 'Lopez',
75
- 'Martin',
76
- 'Martinez',
77
- 'Miller',
78
- 'Moore',
79
- 'Perez',
80
- 'Rahder',
81
- 'Rodriguez',
82
- 'Smith',
83
- 'Taylor',
84
- 'Thomas',
85
- 'Thompson',
86
- 'Uhlig',
87
- 'Waters',
88
- 'White',
89
- 'Williams',
90
- 'Wilson'
39
+ 'Adams', 'Allen', 'Anderson', 'Baker', 'Brown', 'Campbell', 'Carter', 'Clark', 'Davis', 'Flores',
40
+ 'Garcia', 'Gonzales', 'Green', 'Hall', 'Harris', 'Hernandez', 'Hill', 'Jackson', 'Johnson', 'Jones',
41
+ 'King', 'Lee', 'Lewis', 'Lopez', 'Martin', 'Martinez', 'Miller', 'Mitchell', 'Moore', 'Nelson',
42
+ 'Nguyen', 'Perez', 'Rahder', 'Ramirez', 'Roberts', 'Rivera', 'Robinson', 'Rodriguez', 'Sanchez', 'Scott',
43
+ 'Smith', 'Taylor', 'Thomas', 'Thompson', 'Torres', 'Uhlig', 'Walker', 'Waters', 'White', 'Williams',
44
+ 'Wilson', 'Wright', 'Young'
91
45
  ]
92
46
 
93
47
  /**
@@ -106,12 +106,11 @@ class MainContainer extends ConfigurationViewport {
106
106
  */
107
107
  createExampleComponent() {
108
108
  return {
109
- module : GridContainer,
110
- bind : {store : 'stores.mainStore'},
111
- cellEditing : true,
112
- parentId : this.id,
113
- selectionModel: CellModel,
114
- store : MainStore,
109
+ module : GridContainer,
110
+ bind : {store: 'stores.mainStore'},
111
+ cellEditing: true,
112
+ parentId : this.id,
113
+ store : MainStore,
115
114
 
116
115
  columnDefaults: {
117
116
  editable: true,
@@ -159,7 +158,11 @@ class MainContainer extends ConfigurationViewport {
159
158
  dataField: 'githubId',
160
159
  editable : false,
161
160
  text : 'Github Id (Non-editable)'
162
- }]
161
+ }],
162
+
163
+ viewConfig: {
164
+ selectionModel: CellModel
165
+ }
163
166
  }
164
167
  }
165
168
 
@@ -25,7 +25,8 @@ class MainContainer extends ConfigurationViewport {
25
25
  }
26
26
 
27
27
  createConfigurationComponents() {
28
- let me = this;
28
+ let me = this,
29
+ {view} = me.exampleComponent;
29
30
 
30
31
  const selectionModelRadioDefaults = {
31
32
  module : Radio,
@@ -45,34 +46,34 @@ class MainContainer extends ConfigurationViewport {
45
46
  value : me.exampleComponent.height
46
47
  }, {
47
48
  ...selectionModelRadioDefaults,
48
- checked : me.exampleComponent.selectionModel.ntype === 'selection-grid-cellmodel',
49
+ checked : view.selectionModel.ntype === 'selection-grid-cellmodel',
49
50
  labelText : 'selectionModel',
50
51
  listeners : {change: me.onRadioChange.bind(me, 'selectionModel', CellModel)},
51
52
  style : {marginTop: '10px'},
52
53
  valueLabelText: 'Cell'
53
54
  }, {
54
55
  ...selectionModelRadioDefaults,
55
- checked : me.exampleComponent.selectionModel.ntype === 'selection-grid-columnmodel',
56
+ checked : view.selectionModel.ntype === 'selection-grid-columnmodel',
56
57
  listeners : {change: me.onRadioChange.bind(me, 'selectionModel', ColumnModel)},
57
58
  valueLabelText: 'Column'
58
59
  }, {
59
60
  ...selectionModelRadioDefaults,
60
- checked : me.exampleComponent.selectionModel.ntype === 'selection-grid-rowmodel',
61
+ checked : view.selectionModel.ntype === 'selection-grid-rowmodel',
61
62
  listeners : {change: me.onRadioChange.bind(me, 'selectionModel', RowModel)},
62
63
  valueLabelText: 'Row'
63
64
  }, {
64
65
  ...selectionModelRadioDefaults,
65
- checked : me.exampleComponent.selectionModel.ntype === 'selection-grid-cellcolumnmodel',
66
+ checked : view.selectionModel.ntype === 'selection-grid-cellcolumnmodel',
66
67
  listeners : {change: me.onRadioChange.bind(me, 'selectionModel', CellColumnModel)},
67
68
  valueLabelText: 'Cell & Column'
68
69
  }, {
69
70
  ...selectionModelRadioDefaults,
70
- checked : me.exampleComponent.selectionModel.ntype === 'selection-grid-cellrowmodel',
71
+ checked : view.selectionModel.ntype === 'selection-grid-cellrowmodel',
71
72
  listeners : {change: me.onRadioChange.bind(me, 'selectionModel', CellRowModel)},
72
73
  valueLabelText: 'Cell & Row'
73
74
  }, {
74
75
  ...selectionModelRadioDefaults,
75
- checked : me.exampleComponent.selectionModel.ntype === 'selection-grid-cellcolumnrowmodel',
76
+ checked : view.selectionModel.ntype === 'selection-grid-cellcolumnrowmodel',
76
77
  listeners : {change: me.onRadioChange.bind(me, 'selectionModel', CellColumnRowModel)},
77
78
  valueLabelText: 'Cell & Column & Row'
78
79
  }]
@@ -80,9 +81,8 @@ class MainContainer extends ConfigurationViewport {
80
81
 
81
82
  createExampleComponent() {
82
83
  return {
83
- module : GridContainer,
84
- selectionModel: CellModel,
85
- store : MainStore,
84
+ module: GridContainer,
85
+ store : MainStore,
86
86
 
87
87
  columnDefaults: {
88
88
  width: 200
@@ -93,7 +93,22 @@ class MainContainer extends ConfigurationViewport {
93
93
  {dataField: 'lastname', text: 'Lastname'},
94
94
  {dataField: 'githubId', text: 'Github Id'},
95
95
  {dataField: 'country', text: 'Country'}
96
- ]
96
+ ],
97
+
98
+ viewConfig: {
99
+ selectionModel: CellModel
100
+ }
101
+ }
102
+ }
103
+
104
+ /**
105
+ * @param {String} config
106
+ * @param {String} value
107
+ * @param {Object} opts
108
+ */
109
+ onRadioChange(config, value, opts) {
110
+ if (opts.value === true) { // we only want to listen to check events, not uncheck
111
+ this.exampleComponent.view[config] = value
97
112
  }
98
113
  }
99
114
  }
@@ -89,9 +89,9 @@ class EditUserDialog extends Dialog {
89
89
  await me.timeout(20);
90
90
 
91
91
  me.getItem('country-field') .value = record.country;
92
- me.getItem('firstname-field').value = record.user.firstname;
93
- me.getItem('lastname-field') .value = record.user.lastname;
94
- me.getItem('selected-field') .checked = record.annotations.selected
92
+ me.getItem('firstname-field').value = record['user.firstname'];
93
+ me.getItem('lastname-field') .value = record['user.lastname'];
94
+ me.getItem('selected-field') .checked = record['annotations.selected'];
95
95
  }
96
96
  }
97
97
 
@@ -99,21 +99,33 @@ class EditUserDialog extends Dialog {
99
99
  * @param {Object} data
100
100
  */
101
101
  onCountryFieldChange(data) {
102
- this.record.country = data.value.code
102
+ // You can also access the internal setter directly:
103
+ // this.record.country = data.value.code
104
+ // Using the API allows bulk changes
105
+
106
+ this.record.set({country: data.value.code})
103
107
  }
104
108
 
105
109
  /**
106
110
  * @param {Object} data
107
111
  */
108
112
  onFirstnameFieldChange(data) {
109
- this.record.user.firstname = data.value
113
+ // You can also access the internal setter directly:
114
+ // this.record['user.firstname'] = data.value
115
+ // Using the API allows bulk changes
116
+ this.record.set({user: {firstname: data.value}})
117
+
118
+
110
119
  }
111
120
 
112
121
  /**
113
122
  * @param {Object} data
114
123
  */
115
124
  onLastnameFieldChange(data) {
116
- this.record.user.lastname = data.value
125
+ // You can also access the internal setter directly:
126
+ // this.record['user.lastname'] = data.value
127
+ // Using the API allows bulk changes
128
+ this.record.set({user: {lastname: data.value}})
117
129
  }
118
130
 
119
131
  /**
@@ -124,11 +136,16 @@ class EditUserDialog extends Dialog {
124
136
  store = me.getStateProvider().getStore('mainStore');
125
137
 
126
138
  if (data.value === false) {
127
- me.record.annotations.selected = false
139
+ // You can also access the internal setter directly:
140
+ // me.record['annotations.selected'] = false
141
+ // Using the API allows bulk changes
142
+ me.record.set({annotations: {selected: false}})
128
143
  } else {
129
144
  // Assuming we want to support a single row selection
130
145
  store.items.forEach(record => {
131
- record.annotations.selected = record === me.record ? data.value : false
146
+ record.set({annotations: {
147
+ selected: record === me.record ? data.value : false
148
+ }})
132
149
  })
133
150
  }
134
151
  }
@@ -2,7 +2,7 @@ import MainStore from './MainStore.mjs';
2
2
  import StateProvider from '../../../src/state/Provider.mjs';
3
3
  import Store from '../../../src/data/Store.mjs';
4
4
 
5
- const countrySymbol = Symbol.for('country');
5
+ const dataSymbol = Symbol.for('data');
6
6
 
7
7
  /**
8
8
  * @class Neo.examples.table.nestedRecordFields.MainContainerStateProvider
@@ -51,7 +51,7 @@ class MainContainerStateProvider extends StateProvider {
51
51
  country = record.country;
52
52
 
53
53
  // hack resetting the current value to get a new record change
54
- record[countrySymbol] = null;
54
+ record[dataSymbol].country = null;
55
55
 
56
56
  record.country = country
57
57
  })
@@ -13,7 +13,7 @@ class MainModel extends Model {
13
13
  type: 'Object',
14
14
 
15
15
  fields: [{
16
- name : 'annotations.selected',
16
+ name : 'selected',
17
17
  type : 'Boolean',
18
18
  defaultValue: false
19
19
  }]
@@ -28,10 +28,10 @@ class MainModel extends Model {
28
28
  type: 'Object',
29
29
 
30
30
  fields: [{
31
- name: 'user.firstname',
31
+ name: 'firstname',
32
32
  type: 'String'
33
33
  }, {
34
- name: 'user.lastname',
34
+ name: 'lastname',
35
35
  type: 'String'
36
36
  }]
37
37
  }]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo.mjs",
3
- "version": "8.4.2",
3
+ "version": "8.6.0",
4
4
  "description": "The webworkers driven UI framework",
5
5
  "type": "module",
6
6
  "repository": {
@@ -49,10 +49,10 @@
49
49
  "autoprefixer": "^10.4.20",
50
50
  "chalk": "^5.4.1",
51
51
  "clean-webpack-plugin": "^4.0.0",
52
- "commander": "^13.0.0",
52
+ "commander": "^13.1.0",
53
53
  "cssnano": "^7.0.6",
54
54
  "envinfo": "^7.14.0",
55
- "fs-extra": "^11.2.0",
55
+ "fs-extra": "^11.3.0",
56
56
  "highlightjs-line-numbers.js": "^2.9.0",
57
57
  "inquirer": "^12.3.2",
58
58
  "marked": "^15.0.6",
@@ -91,7 +91,7 @@ class MainComponent extends Component {
91
91
  let me = this,
92
92
  cls = ['far', 'fa-square'],
93
93
  oldCls = ['fa', 'fa-check'],
94
- node = VdomUtil.findVdomChild(me.vdom, data.path[0].id).vdom;
94
+ node = VdomUtil.find(me.vdom, data.path[0].id).vdom;
95
95
 
96
96
  if (data.path[0].cls.includes('fa-square')) {
97
97
  cls = ['fa', 'fa-check'];
@@ -77,7 +77,7 @@ Use the utility method, replacing the statement referencing the vdom hierarchy.
77
77
 
78
78
  <pre>
79
79
  <s>view.vdom.cn[0].innerHTML = business.title;</s>
80
- Neo.util.VDom.findVdomChild(view.vdom, 'title').vdom.innerHTML = business.title;
80
+ Neo.util.VDom.find(view.vdom, 'title').vdom.innerHTML = business.title;
81
81
  </pre>
82
82
 
83
83
 
@@ -86,17 +86,17 @@ calling the function.
86
86
 
87
87
  Code a new class member.
88
88
 
89
- findVdomChild = Neo.util.VDom.findVdomChild
89
+ find = Neo.util.VDom.find
90
90
 
91
91
  Then use it in the after set method. Here's how that part of the code will look afterwards.
92
92
 
93
93
  <pre style="color:gray; padding: 8px; border: thin solid lightgray;">
94
- findVdomChild = Neo.util.VDom.findVdomChild;
94
+ find = Neo.util.VDom.find;
95
95
 
96
96
  afterSetBusiness(business){
97
97
  if (!business) return;
98
98
  const view = this.getReference('view');
99
- this.findVdomChild(view.vdom, 'title').vdom.innerHTML = business.title;
99
+ this.find(view.vdom, 'title').vdom.innerHTML = business.title;
100
100
  view.update();
101
101
  }
102
102
  </pre>
@@ -129,7 +129,7 @@ Then back in the details view, update the vdom as follows.
129
129
 
130
130
  Then modify the `afterSetBusiness()` method to update the element's `src`.
131
131
 
132
- this.findVdomChild(view.vdom, 'thumbnail').vdom.src = business.imageUrl;
132
+ this.find(view.vdom, 'thumbnail').vdom.src = business.imageUrl;
133
133
 
134
134
  ??Add the address
135
135
 
@@ -184,7 +184,7 @@ of thought and try it. If you get stuck, that code is given in the next lab step
184
184
 
185
185
  Here's one way to code it. How does this compare to your solution?
186
186
 
187
- this.findVdomChild(view.vdom, 'address').vdom.cn = business
187
+ this.find(view.vdom, 'address').vdom.cn = business
188
188
  .address
189
189
  .map(item => ({tag: 'div', innerHTML: item}));
190
190
 
@@ -1,5 +1,9 @@
1
1
  .portal-examples-tab-container.neo-tab-container {
2
-
2
+ .neo-tab-strip {
3
+ .neo-active-tab-indicator {
4
+ background-color: #3E63DD;
5
+ }
6
+ }
3
7
  }
4
8
 
5
9
  // must not be inside the root class to honor the styling for tab button drag&drop
@@ -5,6 +5,10 @@
5
5
  overflow-y : auto;
6
6
  position : relative;
7
7
 
8
+ &:focus {
9
+ outline: none;
10
+ }
11
+
8
12
  .neo-grid-scrollbar {
9
13
  height : 1px;
10
14
  position : absolute;
@@ -262,12 +262,12 @@ const DefaultConfig = {
262
262
  useVdomWorker: true,
263
263
  /**
264
264
  * buildScripts/injectPackageVersion.mjs will update this value
265
- * @default '8.4.2'
265
+ * @default '8.6.0'
266
266
  * @memberOf! module:Neo
267
267
  * @name config.version
268
268
  * @type String
269
269
  */
270
- version: '8.4.2'
270
+ version: '8.6.0'
271
271
  };
272
272
 
273
273
  Object.assign(DefaultConfig, {
package/src/Neo.mjs CHANGED
@@ -320,11 +320,11 @@ Neo = globalThis.Neo = Object.assign({
320
320
  *
321
321
  * @memberOf module:Neo
322
322
  * @param {Array|String} names The class name string containing dots or an Array of the string parts
323
- * @param {Boolean} [create] Set create to true to create empty objects for non-existing parts
323
+ * @param {Boolean} create=false Set create to true to create empty objects for non-existing parts
324
324
  * @param {Object} [scope] Set a different starting point as globalThis
325
325
  * @returns {Object} reference to the toplevel namespace
326
326
  */
327
- ns(names, create, scope) {
327
+ ns(names, create=false, scope) {
328
328
  names = Array.isArray(names) ? names : names.split('.');
329
329
 
330
330
  return names.reduce((prev, current) => {
@@ -342,11 +342,11 @@ Neo = globalThis.Neo = Object.assign({
342
342
  * Extended version of Neo.ns() which supports mapping into arrays.
343
343
  * @memberOf module:Neo
344
344
  * @param {Array|String} names The class name string containing dots or an Array of the string parts
345
- * @param {Boolean} [create] Set create to true to create empty objects for non-existing parts
345
+ * @param {Boolean} create=false Set create to true to create empty objects for non-existing parts
346
346
  * @param {Object} [scope] Set a different starting point as globalThis
347
347
  * @returns {Object} reference to the toplevel namespace
348
348
  */
349
- nsWithArrays(names, create, scope) {
349
+ nsWithArrays(names, create=false, scope) {
350
350
  names = Array.isArray(names) ? names : names.split('.');
351
351
 
352
352
  return names.reduce((prev, current) => {
@@ -402,9 +402,12 @@ class Component extends Base {
402
402
  }
403
403
 
404
404
  /**
405
- * @member {String[]} childUpdateCache=[]
405
+ * If an update() gets called while a parent is updating, we store the id & distance of the
406
+ * requesting component inside the childUpdateCache of the parent, to get resolved once the update is done.
407
+ * e.g. childUpdateCache = {'neo-grid-view-1': {distance: 1, resolve: fn}}
408
+ * @member {Object} childUpdateCache={}
406
409
  */
407
- childUpdateCache = []
410
+ childUpdateCache = {}
408
411
  /**
409
412
  * Stores the updateDepth while an update is running to enable checks for parent update collisions
410
413
  * @member {Number|null} currentUpdateDepth=null
@@ -1954,7 +1957,7 @@ class Component extends Base {
1954
1957
  console.warn('vdom parent update conflict with:', parent, 'for:', me)
1955
1958
  }
1956
1959
 
1957
- NeoArray.add(parent.childUpdateCache, me.id);
1960
+ parent.childUpdateCache[me.id] = {distance, resolve};
1958
1961
 
1959
1962
  // Adding the resolve fn to its own cache, since the parent will trigger
1960
1963
  // a new update() directly on this cmp
@@ -2335,22 +2338,46 @@ class Component extends Base {
2335
2338
  * @protected
2336
2339
  */
2337
2340
  resolveVdomUpdate(resolve) {
2338
- let me = this;
2341
+ let me = this,
2342
+ hasChildUpdateCache = !Neo.isEmpty(me.childUpdateCache),
2343
+ component;
2339
2344
 
2340
2345
  me.doResolveUpdateCache();
2341
2346
 
2342
2347
  resolve?.();
2343
2348
 
2344
2349
  if (me.needsVdomUpdate) {
2345
- // if a new update is scheduled, we can clear the cache => these updates are included
2346
- me.childUpdateCache = [];
2350
+ if (hasChildUpdateCache) {
2351
+ Object.entries(me.childUpdateCache).forEach(([key, value]) => {
2352
+ component = Neo.getComponent(key);
2353
+
2354
+ // The component might already got destroyed
2355
+ if (component) {
2356
+ // Pass callbacks to the resolver cache => getting executed once the following update is done
2357
+ value.resolve && NeoArray.add(me.resolveUpdateCache, value.resolve);
2358
+
2359
+ // Adjust the updateDepth to include the depth of all merged child updates
2360
+ if (me.updateDepth !== -1) {
2361
+ if (component.updateDepth === -1) {
2362
+ me.updateDepth = -1
2363
+ } else {
2364
+ // Since updateDepth is 1-based, we need to subtract 1 level
2365
+ me.updateDepth = me.updateDepth + value.distance + component.updateDepth - 1
2366
+ }
2367
+ }
2368
+ }
2369
+ });
2370
+
2371
+ me.childUpdateCache = {}
2372
+ }
2347
2373
 
2348
2374
  me.update()
2349
- } else if (me.childUpdateCache) {
2350
- [...me.childUpdateCache].forEach(id => {
2351
- Neo.getComponent(id)?.update();
2352
- NeoArray.remove(me.childUpdateCache, id)
2353
- })
2375
+ } else if (hasChildUpdateCache) {
2376
+ Object.keys(me.childUpdateCache).forEach(key => {
2377
+ Neo.getComponent(key)?.update()
2378
+ });
2379
+
2380
+ me.childUpdateCache = {}
2354
2381
  }
2355
2382
  }
2356
2383