@cc-component/cc-ex-component 1.2.8 → 1.3.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.
Files changed (47) hide show
  1. package/assets/core/BaseReference.ts +10 -1
  2. package/assets/core/BaseReference.ts.meta +1 -1
  3. package/assets/core/BaseViewModelData.ts.meta +1 -1
  4. package/assets/core/ReferenceComponent.ts +15 -9
  5. package/assets/core/ReferenceComponent.ts.meta +1 -1
  6. package/assets/core/ViewModel.ts +170 -171
  7. package/assets/core/ViewModel.ts.meta +1 -1
  8. package/assets/core.meta +1 -1
  9. package/assets/ex/EXButton.ts.meta +1 -1
  10. package/assets/ex/ExCommon.ts.meta +1 -1
  11. package/assets/ex/ExTool.ts.meta +1 -1
  12. package/assets/ex/ExTween.ts.meta +1 -1
  13. package/assets/ex.meta +1 -1
  14. package/assets/lib/collectView/lib-ext/custom-grid-flow-layout.ts.meta +1 -1
  15. package/assets/lib/collectView/lib-ext/horizontal-center-layout.ts.meta +1 -1
  16. package/assets/lib/collectView/lib-ext/yx-card-page-layout.ts.meta +1 -1
  17. package/assets/lib/collectView/lib-ext/yx-carousel-layout.ts.meta +1 -1
  18. package/assets/lib/collectView/lib-ext/yx-cover-layout.ts.meta +1 -1
  19. package/assets/lib/collectView/lib-ext/yx-masonry-flow-layout.ts.meta +1 -1
  20. package/assets/lib/collectView/lib-ext/yx-page-view.ts.meta +1 -1
  21. package/assets/lib/collectView/lib-ext/yx-table-view.ts.meta +1 -1
  22. package/assets/lib/collectView/lib-ext.meta +1 -1
  23. package/assets/lib/collectView/lib_collect/yx-collection-view.ts +14 -0
  24. package/assets/lib/collectView/lib_collect/yx-collection-view.ts.meta +1 -1
  25. package/assets/lib/collectView/lib_collect/yx-compact-flow-layout.ts.meta +1 -1
  26. package/assets/lib/collectView/lib_collect/yx-flow-layout.ts +12 -5
  27. package/assets/lib/collectView/lib_collect/yx-flow-layout.ts.meta +1 -1
  28. package/assets/lib/collectView/lib_collect/yx-page-layout.ts +100 -0
  29. package/assets/lib/collectView/lib_collect/yx-page-layout.ts.meta +9 -0
  30. package/assets/lib/collectView/lib_collect/yx-table-layout.ts.meta +1 -1
  31. package/assets/lib/collectView/lib_collect.meta +1 -1
  32. package/assets/lib/collectView.meta +1 -1
  33. package/assets/lib/tableView/IListView.ts.meta +1 -1
  34. package/assets/lib/tableView/ListView.ts +1 -1
  35. package/assets/lib/tableView/ListView.ts.meta +1 -1
  36. package/assets/lib/tableView/ListViewPage.ts +56 -20
  37. package/assets/lib/tableView/ListViewPage.ts.meta +1 -1
  38. package/assets/lib/tableView/ListViewPageLoop.ts +1 -1
  39. package/assets/lib/tableView/ListViewPageLoop.ts.meta +1 -1
  40. package/assets/lib/tableView/TableView.ts +22 -2
  41. package/assets/lib/tableView/TableView.ts.meta +1 -1
  42. package/assets/lib/tableView.meta +1 -1
  43. package/assets/lib.meta +1 -1
  44. package/assets.meta +1 -1
  45. package/index.ts.meta +1 -1
  46. package/package.json +1 -1
  47. package/package.json.meta +1 -1
@@ -18,8 +18,12 @@ export class BaseReference extends Component {
18
18
  }
19
19
 
20
20
  onLoadFinish() {
21
- if (this.vmParams) this.viewModel?.refreshUI(this.vmParams)
21
+ if (this.vmParams) {
22
+ this.viewModel?.refreshUI(this.vmParams)
23
+ // this.vmParams = null
24
+ }
22
25
  }
26
+
23
27
  //#endregion
24
28
  defineProperty(propertyKey: string) {
25
29
  Object.defineProperty(this, propertyKey, { get: () => this.rc?.get(propertyKey), set: (value) => { }, configurable: true });
@@ -28,6 +32,11 @@ export class BaseReference extends Component {
28
32
 
29
33
  refreshUI(vmParams: any) {
30
34
  this.vmParams = vmParams;
35
+ if (this.vmParams) {
36
+ this.viewModel?.refreshUI(this.vmParams)
37
+ /// this.vmParams = null
38
+ }
39
+
31
40
  }
32
41
  protected onDestroy(): void {
33
42
 
@@ -2,7 +2,7 @@
2
2
  "ver": "4.0.24",
3
3
  "importer": "typescript",
4
4
  "imported": true,
5
- "uuid": "80f3a1bc-0def-46f0-9d80-766558915dba",
5
+ "uuid": "98261244-ef30-417a-bedf-15c9cb6ad132",
6
6
  "files": [],
7
7
  "subMetas": {},
8
8
  "userData": {}
@@ -2,7 +2,7 @@
2
2
  "ver": "4.0.24",
3
3
  "importer": "typescript",
4
4
  "imported": true,
5
- "uuid": "b0c7d937-f05a-4775-b75a-37fd1c14f007",
5
+ "uuid": "e59e775b-f518-478a-9c7f-ce9ffa52d555",
6
6
  "files": [],
7
7
  "subMetas": {},
8
8
  "userData": {}
@@ -1,5 +1,6 @@
1
1
  import { Sprite } from "cc";
2
2
  import { assetManager } from "cc";
3
+ import { Button } from "cc";
3
4
  import { Enum } from "cc";
4
5
  import { _decorator, Component, js, Node } from "cc";
5
6
  import { EDITOR_NOT_IN_PREVIEW } from "cc/env";
@@ -84,6 +85,7 @@ export class ReferenceComponent extends Component {
84
85
  comList2 = ["YXCollectionView", "TableView"]
85
86
  comList_base = ["EditBox", "Toggle", "ToggleContainer", "Slider", "Button", "ProgressBar"]
86
87
 
88
+ skipList = ["Button"]//跳过按钮类型
87
89
  protected onLoad(): void {
88
90
  if (EDITOR_NOT_IN_PREVIEW) {//处理编辑器逻辑
89
91
  this.initNodeList();
@@ -212,7 +214,6 @@ export class ReferenceComponent extends Component {
212
214
  public refreshUI(data: ${iinterface}) { super.refreshUI(data); }
213
215
 
214
216
  // ✅ 使用新装饰器(自动响应式 + 路径推导)
215
- @BindViewModel(${className}Data)
216
217
  viewModel: ${className}Data;`
217
218
  text += viewModel + "\n\n"
218
219
  text += ` // ✅ UI属性`
@@ -253,10 +254,12 @@ export class ReferenceComponent extends Component {
253
254
  bind_pix = `@BindTable`
254
255
  }
255
256
 
256
- let bind = `${bind_pix}("${name}"${this.comList.includes(type) ? event : ""})`
257
- if (true) {
258
- bind = `${bind_pix}("${name}"${this.comList2.includes(type) ? event : ""})`
257
+
258
+ let bind = `${bind_pix}("${name}"${this.comList2.includes(type) ? event : ""})`
259
+ if (this.skipList.includes(type)) {
260
+ bind = `${bind_pix}()`
259
261
  }
262
+
260
263
  if (this.comList_base.includes(type)) {
261
264
 
262
265
  eventStr += `
@@ -299,12 +302,14 @@ export class ReferenceComponent extends Component {
299
302
  let key = data.key;
300
303
  let name = key[0].toLowerCase() + key.substring(1);
301
304
  const type = this.getPropertyType(data.com)
302
- //@ts-ignore
303
- let line = ` ${name}: ${this.getDataTypeByComponentType(type)};`//`private get ${name}() { return this.rc.get("${key}", ${this.getPropertyType(data.node)}); }`;
304
- sx += line + "" + (index < this.nodes.length - 1 ? "\n" : "");
305
+ if (!this.skipList.includes(type)) {
306
+ //@ts-ignore
307
+ let line = ` ${name}: ${this.getDataTypeByComponentType(type)};`//`private get ${name}() { return this.rc.get("${key}", ${this.getPropertyType(data.node)}); }`;
308
+ sx += line + "" + (index < this.nodes.length - 1 ? "\n" : "");
305
309
 
306
- let line_sx = ` this.${name} = ${this.getDataTypeByComponentTypeValue(type)}`
307
- sx_this += line_sx + (index < this.nodes.length - 1 ? "\n" : "");
310
+ let line_sx = ` this.${name} = ${this.getDataTypeByComponentTypeValue(type)}`
311
+ sx_this += line_sx + (index < this.nodes.length - 1 ? "\n" : "");
312
+ }
308
313
  });
309
314
 
310
315
  text = `
@@ -371,6 +376,7 @@ const { ccclass, property } = _decorator;
371
376
  this.viewModel.loadData()
372
377
  }`
373
378
  const classView = `
379
+ @BindViewModel(${className}Data)
374
380
  @ccclass('${className}')
375
381
  export class ${className} extends ViewModel(BaseReference) {${sx.text}\n${onload}\n\n${sx.event}\n}`
376
382
 
@@ -2,7 +2,7 @@
2
2
  "ver": "4.0.24",
3
3
  "importer": "typescript",
4
4
  "imported": true,
5
- "uuid": "f34b484e-1368-4fe7-b8a5-432c5db1d7db",
5
+ "uuid": "68335bb8-9bdb-4226-9099-45c109a36775",
6
6
  "files": [],
7
7
  "subMetas": {},
8
8
  "userData": {}
@@ -16,10 +16,12 @@ import { YXFlowLayout } from '../lib/collectView/lib_collect/yx-flow-layout';
16
16
  import { math } from 'cc';
17
17
  import { YXCollectionView, YXIndexPath } from '../lib/collectView/lib_collect/yx-collection-view';
18
18
  import { EventTouch } from 'cc';
19
+ import { YXPagelayout } from '../lib/collectView/lib_collect/yx-page-layout';
19
20
 
20
21
  interface IBindingData extends ITableViewEvents, IBindingDataEvents {
21
22
  dataPath: string;
22
23
  type: any;
24
+ propertyKey?: string;
23
25
  // 允许任意额外属性
24
26
  [key: string]: any;
25
27
  }
@@ -73,6 +75,50 @@ export const refMap: Map<string, string[]> = new Map();
73
75
  // "cc.Toggle": Toggle,
74
76
  // "cc.Button": Button,
75
77
  // }
78
+ export function BindViewModel<T extends new () => any>(constructor: T) {
79
+ return function (target: any) {
80
+ const onLoad = target.prototype.onLoad;
81
+ /**
82
+ * 重载onload 注入更新
83
+ */
84
+ target.prototype.onLoad = function () {
85
+ onLoad.call(this);
86
+ const className = js.getClassName(target);
87
+ if (!bindingMap.has(className)) {
88
+ bindingMap.set(className, new Map());
89
+ }
90
+ //console.log('onLoad我的', this.node.name)
91
+ if (!this._bindings) this._bindings = [];
92
+
93
+ const map = bindingMap.get(className)
94
+ for (const [propertyKey, value] of map) {
95
+ //属性绑定
96
+ this.initReferenceCollector();
97
+ this.defineProperty(propertyKey);
98
+
99
+ //设置类型
100
+ const com = this[propertyKey];
101
+ const classname = js.getClassName(com)
102
+ value.type = classname
103
+ // console.log('属性绑定', propertyKey, value.type, com, this)
104
+ // 记录绑定关系到实例
105
+ this._bindings.push({ uiProp: value.propertyKey, dataPath: value.dataPath });
106
+ // 初始化 UI
107
+ const value_data = this._getNestedValue(this, value.dataPath);
108
+ const data = map.get(propertyKey)
109
+ updateStatus(data, com, value_data, this);
110
+ }
111
+
112
+ // 创建实例并转为响应式
113
+ const vm_data = 'viewModel'
114
+ const instance = new constructor();
115
+ this[vm_data] = this._makeReactive(instance, vm_data);
116
+
117
+ this.onLoadFinish();
118
+ };
119
+ };
120
+
121
+ }
76
122
 
77
123
  /**
78
124
  * 数据绑定装饰器
@@ -80,50 +126,35 @@ export const refMap: Map<string, string[]> = new Map();
80
126
  * @param reset 重写赋值方法,自定义实现. 参数:(self 组件所在的父类,com 组件,value 值)
81
127
  * @param event 点击事件,滑动事件,等等. 参数:(self 组件所在的父类)
82
128
  */
83
- export function Bind<T extends Component>(dataPath: string, param?: IBindingDataEvents) {
84
- dataPath = baseData + '.' + dataPath;
129
+ export function Bind<T extends Component>(path?: string, param?: IBindingDataEvents) {
130
+ const dataPath = baseData + '.' + path;
85
131
  return function (target: any, propertyKey: string) {
86
- const className = js.getClassName(target.constructor);
87
- if (!bindingMap.has(className)) {
88
- bindingMap.set(className, new Map());
89
- }
132
+ const className = js.getClassName(target);
90
133
  const data: IBindingData = {
91
- dataPath: dataPath, type: null, reset: param?.reset, event: param?.event,
134
+ propertyKey: propertyKey,
135
+ dataPath: dataPath, type: className, reset: param?.reset, event: param?.event,
92
136
  itemSize: null,
93
137
  cellForItemAt: null,
94
138
  numberOfItems: null,
139
+ touchStart: param?.touchStart,
140
+ touchMove: param?.touchMove,
141
+ touchEnd: param?.touchEnd,
142
+ touchCancel: param?.touchCancel,
95
143
  }
96
144
 
145
+ if (!bindingMap.has(className)) { bindingMap.set(className, new Map()); }
97
146
  bindingMap.get(className)!.set(propertyKey, data);
98
- // 重写 onLoad 以初始化绑定
99
- const originalOnLoad = target.constructor.prototype.onLoad;
100
- target.constructor.prototype.onLoad = function () {
101
- originalOnLoad?.call(this);
102
- const com = this[propertyKey];
103
- const classname = js.getClassName(com)
104
- data.type = classname;
105
- bindingMap.get(className)!.set(propertyKey, data);
106
- // 初始化 UI
107
- const value = this._getNestedValue(this, dataPath);
108
- if (com) {
109
- updateStatus(data, com, value, this)
110
- }
111
-
112
- // 记录绑定关系到实例
113
- if (!this._bindings) this._bindings = [];
114
- this._bindings.push({ uiProp: propertyKey, dataPath });
115
- };
116
147
  };
117
148
  }
118
149
 
150
+
119
151
  export function BindTable<T extends Component>(dataPath: string, param?: ITableViewEvents) {
120
152
  dataPath = baseData + '.' + dataPath;
121
153
  return function (target: any, propertyKey: string) {
122
154
  const className = js.getClassName(target.constructor);
123
- if (!bindingMap.has(className)) {
124
- bindingMap.set(className, new Map());
125
- }
126
155
  const data: IBindingData = {
156
+ propertyKey: propertyKey,
157
+
127
158
  dataPath: dataPath, type: null,
128
159
  itemSize: param.itemSize,
129
160
  cellForItemAt: param.cellForItemAt,
@@ -131,26 +162,8 @@ export function BindTable<T extends Component>(dataPath: string, param?: ITableV
131
162
  onTouchCellAt: param.onTouchCellAt,
132
163
  moveFinish: param.moveFinish,
133
164
  }
134
-
165
+ if (!bindingMap.has(className)) { bindingMap.set(className, new Map()); }
135
166
  bindingMap.get(className)!.set(propertyKey, data);
136
- // 重写 onLoad 以初始化绑定
137
- const originalOnLoad = target.constructor.prototype.onLoad;
138
- target.constructor.prototype.onLoad = function () {
139
- originalOnLoad?.call(this);
140
- const com = this[propertyKey];
141
- const classname = js.getClassName(com)
142
- data.type = classname;
143
- bindingMap.get(className)!.set(propertyKey, data);
144
- // 初始化 UI
145
- const value = this._getNestedValue(this, dataPath);
146
- if (com) {
147
- updateStatus(data, com, value, this)
148
- }
149
-
150
- // 记录绑定关系到实例
151
- if (!this._bindings) this._bindings = [];
152
- this._bindings.push({ uiProp: propertyKey, dataPath });
153
- };
154
167
  };
155
168
  }
156
169
 
@@ -158,11 +171,9 @@ export function BindCollect<T extends Component>(dataPath: string, param?: IColl
158
171
  dataPath = baseData + '.' + dataPath;
159
172
  return function (target: any, propertyKey: string) {
160
173
  const className = js.getClassName(target.constructor);
161
- if (!bindingMap.has(className)) {
162
- bindingMap.set(className, new Map());
163
- }
164
174
 
165
175
  const data: IBindingData = {
176
+ propertyKey: propertyKey,
166
177
  dataPath: dataPath, type: null,
167
178
  layout: param.layout,
168
179
  cellForItemAt: param.cellForItemAt as any,
@@ -170,31 +181,8 @@ export function BindCollect<T extends Component>(dataPath: string, param?: IColl
170
181
  itemSize: param.itemSize as any,
171
182
  onTouchCellAt: param.onTouchCellAt,
172
183
  }
173
-
174
- // layout: (self: any) => YXFlowLayout,
175
- // cellForItemAt: (self: any, indexPath: YXIndexPath, collectionView: YXCollectionView) => Node
176
- // itemSize?: ((self: any, indexPath: YXIndexPath, layout: YXFlowLayout, collectionView: YXCollectionView) => math.Size),
177
- // onTouchCellAt?: (self: any, indexPath: YXIndexPath) => void
178
- // numberOfItems?: ((self: any, section: number, collectionView: YXCollectionView) => number);
184
+ if (!bindingMap.has(className)) { bindingMap.set(className, new Map()); }
179
185
  bindingMap.get(className)!.set(propertyKey, data);
180
- // 重写 onLoad 以初始化绑定
181
- const originalOnLoad = target.constructor.prototype.onLoad;
182
- target.constructor.prototype.onLoad = function () {
183
- originalOnLoad?.call(this);
184
- const com = this[propertyKey];
185
- const classname = js.getClassName(com)
186
- data.type = classname;
187
- bindingMap.get(className)!.set(propertyKey, data);
188
- // 初始化 UI
189
- const value = this._getNestedValue(this, dataPath);
190
- if (com) {
191
- updateStatus(data, com, value, this)
192
- }
193
-
194
- // 记录绑定关系到实例
195
- if (!this._bindings) this._bindings = [];
196
- this._bindings.push({ uiProp: propertyKey, dataPath });
197
- };
198
186
  };
199
187
  }
200
188
  /**
@@ -285,19 +273,20 @@ function updateStatus(data: IBindingData, com: Component, value: any, self: any)
285
273
 
286
274
  const sx = data.dataPath.split('.').pop();
287
275
  const tempData = { value: value, skip: false }
276
+ //console.log("updateStatus", data.propertyKey)
288
277
  switch (data.type) {
289
278
  case 'cc.Label':
290
279
  if (data.reset) {
291
280
  data.reset(self, value, com);
292
281
  } else {
293
- if (value) (com as Label).string = value?.toString() || '';
282
+ if (value != undefined && value !== null) (com as Label).string = value?.toString() || '';
294
283
  }
295
284
  break;
296
285
  case 'cc.RichText':
297
286
  if (data.reset) {
298
287
  data.reset(self, value, com);
299
288
  } else
300
- if (value)
289
+ if (value != undefined && value !== null)
301
290
  (com as RichText).string = value?.toString() || '';
302
291
  break;
303
292
  case 'cc.Sprite':
@@ -306,7 +295,7 @@ function updateStatus(data: IBindingData, com: Component, value: any, self: any)
306
295
  if (data.reset) {
307
296
  data.reset(self, value, com);
308
297
  } else
309
- if (value) (com as Sprite).spriteFrame = value;
298
+ if (value != undefined && value !== null) (com as Sprite).spriteFrame = value;
310
299
  break;
311
300
  case 'cc.Button':
312
301
  const com_btn = (com as Button);
@@ -316,21 +305,25 @@ function updateStatus(data: IBindingData, com: Component, value: any, self: any)
316
305
  com_btn.node.active = value ?? true;
317
306
 
318
307
  //事件点击
308
+
319
309
  const touch_click = 'CallClick'
320
- com_btn.node.off(Button.EventType.CLICK, com_btn[touch_click]);
321
- tempData.skip = true;
322
- const btnCall = (btn) => {
323
- tempData.value = btn.node.active
324
- self.viewModel[sx] = tempData
325
- data.event?.(self)
326
- self[`onClick_${sx}`]?.(btn)
310
+ if (!com_btn[touch_click]) {
311
+ const sx = data.propertyKey;
312
+ com_btn.node.off(Button.EventType.CLICK, com_btn[touch_click]);
313
+ tempData.skip = true;
314
+ const btnCall = (btn) => {
315
+ tempData.value = btn.node.active
316
+ self.viewModel[sx] = tempData
317
+ data.event?.(self)
318
+ self[`onClick_${sx}`]?.(btn)
319
+ }
320
+ com_btn[touch_click] = btnCall
321
+ com_btn.node.on(Button.EventType.CLICK, btnCall);
327
322
  }
328
- com_btn[touch_click] = btnCall
329
- com_btn.node.on(Button.EventType.CLICK, com_btn[touch_click]);
330
323
 
331
324
  //touch
332
- if (data.touchStart) {
333
- const touch_start = 'CALL_TOUCH_START'
325
+ let touch_start = 'CALL_TOUCH_START'
326
+ if (data.touchStart && !com_btn[touch_start]) {
334
327
  com_btn.node.off(Node.EventType.TOUCH_START, com_btn[touch_start]);
335
328
  const call_start = (btn) => {
336
329
  data.touchStart?.(self, btn)
@@ -338,8 +331,8 @@ function updateStatus(data: IBindingData, com: Component, value: any, self: any)
338
331
  com_btn[touch_start] = call_start
339
332
  com_btn.node.on(Node.EventType.TOUCH_START, com_btn[touch_start]);
340
333
  }
341
- if (data.touchMove) {
342
- const touch_start = 'CALL_TOUCH_MOVE'
334
+ touch_start = 'CALL_TOUCH_MOVE'
335
+ if (data.touchMove && !com_btn[touch_start]) {
343
336
  com_btn.node.off(Node.EventType.TOUCH_MOVE, com_btn[touch_start]);
344
337
  const call_start = (btn) => {
345
338
  data.touchMove?.(self, btn)
@@ -347,8 +340,8 @@ function updateStatus(data: IBindingData, com: Component, value: any, self: any)
347
340
  com_btn[touch_start] = call_start
348
341
  com_btn.node.on(Node.EventType.TOUCH_MOVE, com_btn[touch_start]);
349
342
  }
350
- if (data.touchEnd) {
351
- const touch_start = 'CALL_TOUCH_END'
343
+ touch_start = 'CALL_TOUCH_END'
344
+ if (data.touchEnd && !com_btn[touch_start]) {
352
345
  com_btn.node.off(Node.EventType.TOUCH_END, com_btn[touch_start]);
353
346
  const call_start = (btn) => {
354
347
  data.touchEnd?.(self, btn)
@@ -356,8 +349,8 @@ function updateStatus(data: IBindingData, com: Component, value: any, self: any)
356
349
  com_btn[touch_start] = call_start
357
350
  com_btn.node.on(Node.EventType.TOUCH_END, com_btn[touch_start]);
358
351
  }
359
- if (data.touchCancel) {
360
- const touch_start = 'CALL_TOUCH_CANCEL'
352
+ touch_start = 'CALL_TOUCH_CANCEL'
353
+ if (data.touchCancel && !com_btn[touch_start]) {
361
354
  com_btn.node.off(Node.EventType.TOUCH_CANCEL, com_btn[touch_start]);
362
355
  const call_start = (btn) => {
363
356
  data.touchCancel?.(self, btn)
@@ -370,70 +363,88 @@ function updateStatus(data: IBindingData, com: Component, value: any, self: any)
370
363
  if (data.reset) {
371
364
  data.reset(self, value, com);
372
365
  } else
373
- if (value) (com as ProgressBar).progress = Number(value) || 0;
366
+ if (value != undefined && value !== null) (com as ProgressBar).progress = Number(value) || 0;
374
367
  break;
375
368
  case 'cc.Skeleton':
376
369
  if (data.reset) {
377
370
  data.reset(self, value, com);
378
371
  } else
379
- if (value) (com as sp.Skeleton).skeletonData = value
372
+ if (value != undefined && value !== null) (com as sp.Skeleton).skeletonData = value
380
373
  break;
381
374
  case 'cc.Slider':
382
- const com_sld = (com as Slider);
383
- if (data.reset) {
384
- data.reset(self, value, com);
385
- } else
386
- if (value) com_sld.progress = Number(value) || 0;
387
-
388
- //事件
389
- com_sld.node.off("slide", com_sld['slideCall'], self)
390
- tempData.skip = true;
391
- const slideCall = (slider) => {
392
- tempData.value = slider.progress
393
- self.viewModel[sx] = tempData
394
- data.event?.(self)
395
- self[`onClick_${sx}`]?.(slider)
375
+ {
376
+ const com_sld = (com as Slider);
377
+ if (data.reset) {
378
+ data.reset(self, value, com);
379
+ } else
380
+ if (value != undefined && value !== null) com_sld.progress = Number(value) || 0;
381
+
382
+ //事件
383
+ const touch_click = 'slideCall'
384
+ if (!com_sld[touch_click]) {
385
+ const sx = data.propertyKey;
386
+ com_sld.node.off("slide", com_sld[touch_click], self)
387
+ tempData.skip = true;
388
+ const slideCall = (slider) => {
389
+ tempData.value = slider.progress
390
+ self.viewModel[sx] = tempData
391
+ data.event?.(self)
392
+ self[`onClick_${sx}`]?.(slider)
393
+ }
394
+ com_sld[touch_click] = slideCall
395
+ com_sld.node.on('slide', slideCall, self);
396
+ }
396
397
  }
397
- com_sld['slideCall'] = slideCall
398
- com_sld.node.on('slide', slideCall, self);
399
398
  break;
400
399
  case 'cc.Toggle':
401
- const com_tg = (com as Toggle);
402
- if (data.reset) {
403
- data.reset(self, value, com);
404
- } else
405
- if (value) com_tg.isChecked = Boolean(value);
406
-
407
- //事件
408
- com_tg.node.off(Toggle.EventType.TOGGLE, com_tg['toggleCall'], self)
409
- tempData.skip = true;
410
- const toggleCall = (toggle) => {
411
- tempData.value = toggle.isChecked
412
- self.viewModel[sx] = tempData
413
- data.event?.(self)
414
- self[`onClick_${sx}`]?.(toggle)
400
+ {
401
+ const com_tg = (com as Toggle);
402
+ if (data.reset) {
403
+ data.reset(self, value, com);
404
+ } else
405
+ if (value != undefined && value !== null) com_tg.isChecked = Boolean(value);
406
+
407
+ //事件
408
+ const touch_click = 'toggleCall'
409
+ if (!com_tg[touch_click]) {
410
+ const sx = data.propertyKey;
411
+ com_tg.node.off(Toggle.EventType.TOGGLE, com_tg[touch_click], self)
412
+ tempData.skip = true;
413
+ const toggleCall = (toggle) => {
414
+ tempData.value = toggle.isChecked
415
+ self.viewModel[sx] = tempData
416
+ data.event?.(self)
417
+ self[`onClick_${sx}`]?.(toggle)
418
+ }
419
+ com_tg[touch_click] = toggleCall
420
+ com_tg.node.on(Toggle.EventType.TOGGLE, toggleCall, self);
421
+ }
415
422
  }
416
- com_tg['toggleCall'] = toggleCall
417
- com_tg.node.on(Toggle.EventType.TOGGLE, toggleCall, self);
418
423
  break;
419
424
  case 'cc.EditBox':
420
- const com_eb = (com as EditBox);
421
- if (data.reset) {
422
- data.reset(self, value, com);
423
- } else
424
- if (value) com_eb.string = value?.toString() || '';
425
-
426
- //事件
427
- com_eb.node.off("text-changed", com_eb['ebCall'], self)
428
- tempData.skip = true;
429
- const ebCall = (editbox: EditBox) => {
430
- tempData.value = editbox.textLabel.string
431
- self.viewModel[sx] = tempData
432
- data.event?.(self)
433
- self[`onClick_${sx}`]?.(editbox)
425
+ {
426
+ const com_eb = (com as EditBox);
427
+ if (data.reset) {
428
+ data.reset(self, value, com);
429
+ } else
430
+ if (value != undefined && value !== null) com_eb.string = value?.toString() || '';
431
+
432
+ //事件
433
+ const touch_click = 'ebCall'
434
+ if (!com_eb[touch_click]) {
435
+ const sx = data.propertyKey;
436
+ com_eb.node.off("text-changed", com_eb[touch_click], self)
437
+ tempData.skip = true;
438
+ const ebCall = (editbox: EditBox) => {
439
+ tempData.value = editbox.textLabel.string
440
+ self.viewModel[sx] = tempData
441
+ data.event?.(self)
442
+ self[`onClick_${sx}`]?.(editbox)
443
+ }
444
+ com_eb[touch_click] = ebCall
445
+ com_eb.node.on('text-changed', ebCall, self);
446
+ }
434
447
  }
435
- com_eb['ebCall'] = ebCall
436
- com_eb.node.on('text-changed', ebCall, self);
437
448
  break;
438
449
  case 'cc.ToggleContainer':
439
450
  {
@@ -444,6 +455,7 @@ function updateStatus(data: IBindingData, com: Component, value: any, self: any)
444
455
 
445
456
  //事件
446
457
  if (com_tgc.checkEvents.length <= 0) {
458
+ const sx = data.propertyKey;
447
459
  const funcName = "onClick_ToggleContainer"
448
460
  const clickEventHandler = new EventHandler();
449
461
  clickEventHandler.target = self.node; // 这个 node 节点是你的事件处理代码组件所属的节点
@@ -474,7 +486,7 @@ function updateStatus(data: IBindingData, com: Component, value: any, self: any)
474
486
  // ✅ 关键:不要缓存 count,而是通过 dataPath 动态取值
475
487
  const getLatestDataLength = () => {
476
488
  const latestValue = self._getNestedValue(self, data.dataPath);
477
- return Array.isArray(latestValue) ? latestValue.length : 0;
489
+ return latestValue ? latestValue.length : 0;
478
490
  };
479
491
 
480
492
  if (com_list.isInit) {
@@ -525,13 +537,21 @@ function updateStatus(data: IBindingData, com: Component, value: any, self: any)
525
537
  // const width = 100
526
538
  // const height = 163
527
539
  // layout.itemSize = math.size(width, height)
528
- table_collection.layout = data.layout()
540
+ table_collection.layout = data.layout(self)
529
541
  // 注册列表内需要使用的 cell 节点类型
530
542
  // 这个演示是通过编辑器绑定的,可以查看场景内 list 节点里的 register cells 配置
531
543
  // this.table_collection.register('cell', () => instantiate('your cell prefab'))
532
544
  // 确定列表内一共需要显示多少条内容
533
545
  // table_collection.isCenterShow = false;//少于宽度,居中显示
534
- table_collection.numberOfItems = () => getLatestDataLength()
546
+ table_collection.numberOfItems = () => {
547
+ const count = data.numberOfItems ? data.numberOfItems(self) : getLatestDataLength()
548
+ if (table_collection.layout instanceof YXPagelayout) {
549
+ table_collection.layout.dataCount = count
550
+ return count * 3
551
+ } else {
552
+ return count
553
+ }
554
+ }
535
555
  table_collection.cellForItemAt = (indexPath, collectionView) => {
536
556
  return data.cellForItemAt(self, indexPath, collectionView as any) // 返回这个节点给列表显示
537
557
  }
@@ -547,8 +567,9 @@ function updateStatus(data: IBindingData, com: Component, value: any, self: any)
547
567
  table_collection.reloadData()
548
568
  }
549
569
  break;
550
- default:
551
- console.error(`请检查类型: ${data.type}`);
570
+ default: {
571
+ if (com) console.error(`请检查类型: ${data.type}`);
572
+ }
552
573
  }
553
574
 
554
575
  }
@@ -560,33 +581,11 @@ function updateStatus(data: IBindingData, com: Component, value: any, self: any)
560
581
  * 响应式数据装饰器
561
582
  * 自动将属性转为响应式对象,并使用属性名作为路径前缀
562
583
  */
563
- export function BindViewModel<T extends new () => any>(constructor: T) {
564
- return function (target: any, propertyKey: string) {
565
- const originalOnLoad = target.constructor.prototype.onLoad;
566
- target.constructor.prototype.onLoad = function () {
567
- // 创建实例并转为响应式
568
- const instance = new constructor();
569
- this[propertyKey] = this._makeReactive(instance, propertyKey);
570
- originalOnLoad?.call(this);
571
- };
572
- };
573
- }
574
584
 
575
585
  // 定义装饰器
576
586
  export function Ref(target: any, propertyKey: string) {
577
-
578
587
  const className = js.getClassName(target)
579
588
  if (!refMap.has(className)) { refMap.set(className, []) }
580
589
  const refList = refMap.get(className)
581
- if (refList.length <= 0) {
582
- const originalOnLoad = target.constructor.prototype.onLoad;
583
- target.constructor.prototype.onLoad = function (this: any) {
584
- this.initReferenceCollector();
585
- this.defineProperty(propertyKey);
586
- originalOnLoad?.call(this);
587
- this.onLoadFinish();
588
- };
589
-
590
- }
591
590
  refList.push(propertyKey)
592
591
  }
@@ -2,7 +2,7 @@
2
2
  "ver": "4.0.24",
3
3
  "importer": "typescript",
4
4
  "imported": true,
5
- "uuid": "91193c30-a004-4bca-bfc0-45fb594eea0f",
5
+ "uuid": "f772ca0d-0c21-4688-9be2-33a210303849",
6
6
  "files": [],
7
7
  "subMetas": {},
8
8
  "userData": {}