@cc-component/cc-ex-component 1.2.7 → 1.2.9

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.
@@ -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
 
@@ -1,4 +1,6 @@
1
1
  import { Sprite } from "cc";
2
+ import { assetManager } from "cc";
3
+ import { Button } from "cc";
2
4
  import { Enum } from "cc";
3
5
  import { _decorator, Component, js, Node } from "cc";
4
6
  import { EDITOR_NOT_IN_PREVIEW } from "cc/env";
@@ -25,6 +27,7 @@ export class ReferenceComponent extends Component {
25
27
  @property({ displayName: "复制属性" })
26
28
  private get refresh() { return this._refresh; }
27
29
  private set refresh(val: boolean) {
30
+ console.error('打印了')
28
31
  if (EDITOR_NOT_IN_PREVIEW) {
29
32
  this.initNodeList();
30
33
  this.genCode();
@@ -82,6 +85,7 @@ export class ReferenceComponent extends Component {
82
85
  comList2 = ["YXCollectionView", "TableView"]
83
86
  comList_base = ["EditBox", "Toggle", "ToggleContainer", "Slider", "Button", "ProgressBar"]
84
87
 
88
+ skipList = ["Button"]//跳过按钮类型
85
89
  protected onLoad(): void {
86
90
  if (EDITOR_NOT_IN_PREVIEW) {//处理编辑器逻辑
87
91
  this.initNodeList();
@@ -187,6 +191,7 @@ export class ReferenceComponent extends Component {
187
191
  text += line;
188
192
  });
189
193
  Editor.Clipboard.write("text", text);
194
+
190
195
  console.log("已复制到剪切板");
191
196
  }
192
197
 
@@ -194,8 +199,8 @@ export class ReferenceComponent extends Component {
194
199
  private genCodeBind(isCopy: boolean = true, isClass: boolean = false) {
195
200
  if (!EDITOR_NOT_IN_PREVIEW) return;
196
201
  let text = "";
197
- let eventStr: string = " //#region 事件"
198
- let pix = "onClick_"
202
+ let eventStr: string = " //#region ⚠️ ------------方法事件"
203
+ let pix = "private onClick_"
199
204
  // const com = this.node.components.find(v => { return v.reference })
200
205
  // const match = com.name.match(/<([^>]+)>/);
201
206
  // const className = match && match[1] ? match[1] : "any"
@@ -203,15 +208,15 @@ export class ReferenceComponent extends Component {
203
208
  let data = `${className}Data`
204
209
  let iinterface = `I${className}Data`
205
210
  //console.error("[MLogger Error]", className)
206
- const viewModel = `
211
+ const viewModel =
212
+ `\n //#region ⚠️ ------------自动生成属性
207
213
  // ✅ 外部界面调用,刷新UI
208
214
  public refreshUI(data: ${iinterface}) { super.refreshUI(data); }
209
215
 
210
- //#region ✅ 使用新装饰器(自动响应式 + 路径推导)
211
- @BindViewModel(${className}Data)
216
+ // ✅ 使用新装饰器(自动响应式 + 路径推导)
212
217
  viewModel: ${className}Data;`
213
218
  text += viewModel + "\n\n"
214
- text += ` //#region ✅ UI属性`
219
+ text += ` // ✅ UI属性`
215
220
  //生成get属性
216
221
  this.nodes.forEach(data => {
217
222
  let key = data.key;
@@ -249,10 +254,12 @@ export class ReferenceComponent extends Component {
249
254
  bind_pix = `@BindTable`
250
255
  }
251
256
 
252
- let bind = `${bind_pix}("${name}"${this.comList.includes(type) ? event : ""})`
253
- if (isClass) {
254
- 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}()`
255
261
  }
262
+
256
263
  if (this.comList_base.includes(type)) {
257
264
 
258
265
  eventStr += `
@@ -265,12 +272,16 @@ export class ReferenceComponent extends Component {
265
272
  let line = ` ${bind} @Ref ${name}: ${type};`
266
273
  text += line;
267
274
  });
275
+ text += `\n //#endregion END`
268
276
 
277
+ text += `\n\n //#region ⚠️ ------------自定义属性`
278
+ text += `\n\n //#endregion END`
269
279
 
270
280
  if (isCopy) {
271
281
  Editor.Clipboard.write("text", text);
272
282
  console.log("已复制到剪切板");
273
283
  }
284
+ eventStr += `\n //#endregion END`
274
285
  return { text: text, event: eventStr }
275
286
 
276
287
  }
@@ -280,33 +291,35 @@ export class ReferenceComponent extends Component {
280
291
  if (!EDITOR_NOT_IN_PREVIEW) return;
281
292
  let text = ""
282
293
  let sx_this = ''
283
- let sx = ' \n'
294
+ let sx = ''
284
295
  const className = this.node.name
285
296
 
286
297
  let data = `${className}Data`
287
298
  let iinterface = `I${className}Data`
288
299
 
289
300
  //生成get属性
290
- this.nodes.forEach(data => {
301
+ this.nodes.forEach((data, index) => {
291
302
  let key = data.key;
292
303
  let name = key[0].toLowerCase() + key.substring(1);
293
304
  const type = this.getPropertyType(data.com)
294
- //@ts-ignore
295
- let line = ` ${name}: ${this.getDataTypeByComponentType(type)};`//`private get ${name}() { return this.rc.get("${key}", ${this.getPropertyType(data.node)}); }`;
296
- sx += line + "\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" : "");
297
309
 
298
- let line_sx = ` this.${name} = ${this.getDataTypeByComponentTypeValue(type)}`
299
- sx_this += line_sx + '\n'
310
+ let line_sx = ` this.${name} = ${this.getDataTypeByComponentTypeValue(type)}`
311
+ sx_this += line_sx + (index < this.nodes.length - 1 ? "\n" : "");
312
+ }
300
313
  });
301
314
 
302
315
  text = `
303
- //#region 数据接口
316
+ //#region ⚠️ ------------数据接口
304
317
  export interface ${iinterface} {
305
318
  ${sx}
306
319
  }
307
- `;
320
+ //#endregion END`;
308
321
  text += `
309
- //#region 数据VM
322
+ //#region ⚠️ ------------数据对象
310
323
  class ${data} extends BaseViewModelData implements ${iinterface} {
311
324
  ${sx}
312
325
 
@@ -315,7 +328,7 @@ ${sx}
315
328
  ${sx_this}
316
329
  }
317
330
  }
318
- `;
331
+ //#endregion END`;
319
332
  if (isCopy) {
320
333
  Editor.Clipboard.write("text", text);
321
334
  console.log("已复制到剪切板");
@@ -331,7 +344,7 @@ ${sx_this}
331
344
  private genCodeVmDataAll() {
332
345
  if (!EDITOR_NOT_IN_PREVIEW) return;
333
346
  let importStr = `
334
- import { Label, RichText, ProgressBar, Sprite, EditBox, Toggle, Slider, ToggleContainer, Button, math, SpriteFrame, _decorator } from 'cc';
347
+ import { Label, RichText, ProgressBar, Sprite, EditBox, Toggle, Slider, ToggleContainer, Button, math, SpriteFrame, _decorator , Node} from 'cc';
335
348
  import { ViewModel, BindViewModel, BindTable, BindCollect, Bind, Ref, BaseViewModelData, YXCollectionView, YXFlowLayout, TableView, BaseReference } from 'db://assets/pkg-export/@cc-component/cc-ex-component';
336
349
  const { ccclass, property } = _decorator;`
337
350
 
@@ -354,7 +367,7 @@ const { ccclass, property } = _decorator;
354
367
 
355
368
  let iinterface = `I${className}Data`
356
369
  const onload = `
357
- //#region 初始化
370
+ //#region ⚠️ ------------初始化
358
371
  onLoad(): void {
359
372
 
360
373
  }
@@ -363,6 +376,7 @@ const { ccclass, property } = _decorator;
363
376
  this.viewModel.loadData()
364
377
  }`
365
378
  const classView = `
379
+ @BindViewModel(${className}Data)
366
380
  @ccclass('${className}')
367
381
  export class ${className} extends ViewModel(BaseReference) {${sx.text}\n${onload}\n\n${sx.event}\n}`
368
382
 
@@ -446,5 +460,4 @@ export class ${className} extends ViewModel(BaseReference) {${sx.text}\n${onload
446
460
  };
447
461
  return typeMap[compType] ?? 'any'; // 默认 fallback
448
462
  }
449
-
450
463
  }
@@ -15,18 +15,25 @@ import { TableView } from '../lib/tableView/TableView';
15
15
  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
+ import { EventTouch } from 'cc';
19
+ import { YXPagelayout } from '../lib/collectView/lib_collect/yx-page-layout';
18
20
 
19
21
  interface IBindingData extends ITableViewEvents, IBindingDataEvents {
20
22
  dataPath: string;
21
23
  type: any;
24
+ propertyKey?: string;
22
25
  // 允许任意额外属性
23
26
  [key: string]: any;
24
27
  }
25
28
 
26
29
 
27
30
  interface IBindingDataEvents {
28
- reset?: Function;
29
- event?: Function;
31
+ reset?: (self: any, value: any, com: Component) => void;
32
+ event?: (self: any) => void;
33
+ touchStart?: (self: any, event: EventTouch) => void;
34
+ touchMove?: (self: any, event: EventTouch) => void;
35
+ touchEnd?: (self: any, event: EventTouch) => void;
36
+ touchCancel?: (self: any, event: EventTouch) => void;
30
37
  }
31
38
 
32
39
 
@@ -68,6 +75,50 @@ export const refMap: Map<string, string[]> = new Map();
68
75
  // "cc.Toggle": Toggle,
69
76
  // "cc.Button": Button,
70
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
+ }
71
122
 
72
123
  /**
73
124
  * 数据绑定装饰器
@@ -75,50 +126,35 @@ export const refMap: Map<string, string[]> = new Map();
75
126
  * @param reset 重写赋值方法,自定义实现. 参数:(self 组件所在的父类,com 组件,value 值)
76
127
  * @param event 点击事件,滑动事件,等等. 参数:(self 组件所在的父类)
77
128
  */
78
- export function Bind<T extends Component>(dataPath: string, param?: IBindingDataEvents) {
79
- dataPath = baseData + '.' + dataPath;
129
+ export function Bind<T extends Component>(path?: string, param?: IBindingDataEvents) {
130
+ const dataPath = baseData + '.' + path;
80
131
  return function (target: any, propertyKey: string) {
81
- const className = js.getClassName(target.constructor);
82
- if (!bindingMap.has(className)) {
83
- bindingMap.set(className, new Map());
84
- }
132
+ const className = js.getClassName(target);
85
133
  const data: IBindingData = {
86
- dataPath: dataPath, type: null, reset: param?.reset, event: param?.event,
134
+ propertyKey: propertyKey,
135
+ dataPath: dataPath, type: className, reset: param?.reset, event: param?.event,
87
136
  itemSize: null,
88
137
  cellForItemAt: null,
89
138
  numberOfItems: null,
139
+ touchStart: param?.touchStart,
140
+ touchMove: param?.touchMove,
141
+ touchEnd: param?.touchEnd,
142
+ touchCancel: param?.touchCancel,
90
143
  }
91
144
 
145
+ if (!bindingMap.has(className)) { bindingMap.set(className, new Map()); }
92
146
  bindingMap.get(className)!.set(propertyKey, data);
93
- // 重写 onLoad 以初始化绑定
94
- const originalOnLoad = target.constructor.prototype.onLoad;
95
- target.constructor.prototype.onLoad = function () {
96
- originalOnLoad?.call(this);
97
- const com = this[propertyKey];
98
- const classname = js.getClassName(com)
99
- data.type = classname;
100
- bindingMap.get(className)!.set(propertyKey, data);
101
- // 初始化 UI
102
- const value = this._getNestedValue(this, dataPath);
103
- if (com) {
104
- updateStatus(data, com, value, this)
105
- }
106
-
107
- // 记录绑定关系到实例
108
- if (!this._bindings) this._bindings = [];
109
- this._bindings.push({ uiProp: propertyKey, dataPath });
110
- };
111
147
  };
112
148
  }
113
149
 
150
+
114
151
  export function BindTable<T extends Component>(dataPath: string, param?: ITableViewEvents) {
115
152
  dataPath = baseData + '.' + dataPath;
116
153
  return function (target: any, propertyKey: string) {
117
154
  const className = js.getClassName(target.constructor);
118
- if (!bindingMap.has(className)) {
119
- bindingMap.set(className, new Map());
120
- }
121
155
  const data: IBindingData = {
156
+ propertyKey: propertyKey,
157
+
122
158
  dataPath: dataPath, type: null,
123
159
  itemSize: param.itemSize,
124
160
  cellForItemAt: param.cellForItemAt,
@@ -126,26 +162,8 @@ export function BindTable<T extends Component>(dataPath: string, param?: ITableV
126
162
  onTouchCellAt: param.onTouchCellAt,
127
163
  moveFinish: param.moveFinish,
128
164
  }
129
-
165
+ if (!bindingMap.has(className)) { bindingMap.set(className, new Map()); }
130
166
  bindingMap.get(className)!.set(propertyKey, data);
131
- // 重写 onLoad 以初始化绑定
132
- const originalOnLoad = target.constructor.prototype.onLoad;
133
- target.constructor.prototype.onLoad = function () {
134
- originalOnLoad?.call(this);
135
- const com = this[propertyKey];
136
- const classname = js.getClassName(com)
137
- data.type = classname;
138
- bindingMap.get(className)!.set(propertyKey, data);
139
- // 初始化 UI
140
- const value = this._getNestedValue(this, dataPath);
141
- if (com) {
142
- updateStatus(data, com, value, this)
143
- }
144
-
145
- // 记录绑定关系到实例
146
- if (!this._bindings) this._bindings = [];
147
- this._bindings.push({ uiProp: propertyKey, dataPath });
148
- };
149
167
  };
150
168
  }
151
169
 
@@ -153,11 +171,9 @@ export function BindCollect<T extends Component>(dataPath: string, param?: IColl
153
171
  dataPath = baseData + '.' + dataPath;
154
172
  return function (target: any, propertyKey: string) {
155
173
  const className = js.getClassName(target.constructor);
156
- if (!bindingMap.has(className)) {
157
- bindingMap.set(className, new Map());
158
- }
159
174
 
160
175
  const data: IBindingData = {
176
+ propertyKey: propertyKey,
161
177
  dataPath: dataPath, type: null,
162
178
  layout: param.layout,
163
179
  cellForItemAt: param.cellForItemAt as any,
@@ -165,31 +181,8 @@ export function BindCollect<T extends Component>(dataPath: string, param?: IColl
165
181
  itemSize: param.itemSize as any,
166
182
  onTouchCellAt: param.onTouchCellAt,
167
183
  }
168
-
169
- // layout: (self: any) => YXFlowLayout,
170
- // cellForItemAt: (self: any, indexPath: YXIndexPath, collectionView: YXCollectionView) => Node
171
- // itemSize?: ((self: any, indexPath: YXIndexPath, layout: YXFlowLayout, collectionView: YXCollectionView) => math.Size),
172
- // onTouchCellAt?: (self: any, indexPath: YXIndexPath) => void
173
- // numberOfItems?: ((self: any, section: number, collectionView: YXCollectionView) => number);
184
+ if (!bindingMap.has(className)) { bindingMap.set(className, new Map()); }
174
185
  bindingMap.get(className)!.set(propertyKey, data);
175
- // 重写 onLoad 以初始化绑定
176
- const originalOnLoad = target.constructor.prototype.onLoad;
177
- target.constructor.prototype.onLoad = function () {
178
- originalOnLoad?.call(this);
179
- const com = this[propertyKey];
180
- const classname = js.getClassName(com)
181
- data.type = classname;
182
- bindingMap.get(className)!.set(propertyKey, data);
183
- // 初始化 UI
184
- const value = this._getNestedValue(this, dataPath);
185
- if (com) {
186
- updateStatus(data, com, value, this)
187
- }
188
-
189
- // 记录绑定关系到实例
190
- if (!this._bindings) this._bindings = [];
191
- this._bindings.push({ uiProp: propertyKey, dataPath });
192
- };
193
186
  };
194
187
  }
195
188
  /**
@@ -280,19 +273,20 @@ function updateStatus(data: IBindingData, com: Component, value: any, self: any)
280
273
 
281
274
  const sx = data.dataPath.split('.').pop();
282
275
  const tempData = { value: value, skip: false }
276
+ //console.log("updateStatus", data.propertyKey)
283
277
  switch (data.type) {
284
278
  case 'cc.Label':
285
279
  if (data.reset) {
286
280
  data.reset(self, value, com);
287
281
  } else {
288
- if (value) (com as Label).string = value?.toString() || '';
282
+ if (value != undefined && value !== null) (com as Label).string = value?.toString() || '';
289
283
  }
290
284
  break;
291
285
  case 'cc.RichText':
292
286
  if (data.reset) {
293
287
  data.reset(self, value, com);
294
288
  } else
295
- if (value)
289
+ if (value != undefined && value !== null)
296
290
  (com as RichText).string = value?.toString() || '';
297
291
  break;
298
292
  case 'cc.Sprite':
@@ -301,7 +295,7 @@ function updateStatus(data: IBindingData, com: Component, value: any, self: any)
301
295
  if (data.reset) {
302
296
  data.reset(self, value, com);
303
297
  } else
304
- if (value) (com as Sprite).spriteFrame = value;
298
+ if (value != undefined && value !== null) (com as Sprite).spriteFrame = value;
305
299
  break;
306
300
  case 'cc.Button':
307
301
  const com_btn = (com as Button);
@@ -310,86 +304,147 @@ function updateStatus(data: IBindingData, com: Component, value: any, self: any)
310
304
  } else
311
305
  com_btn.node.active = value ?? true;
312
306
 
313
- //事件
314
- com_btn.node.off(Button.EventType.CLICK, com_btn['btnCall']);
315
- tempData.skip = true;
316
- const btnCall = (btn) => {
317
- tempData.value = btn.node.active
318
- self.viewModel[sx] = tempData
319
- data.event?.(self)
320
- self[`onClick_${sx}`]?.(btn)
307
+ //事件点击
308
+
309
+ const touch_click = 'CallClick'
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);
322
+ }
323
+
324
+ //touch
325
+ let touch_start = 'CALL_TOUCH_START'
326
+ if (data.touchStart && !com_btn[touch_start]) {
327
+ com_btn.node.off(Node.EventType.TOUCH_START, com_btn[touch_start]);
328
+ const call_start = (btn) => {
329
+ data.touchStart?.(self, btn)
330
+ }
331
+ com_btn[touch_start] = call_start
332
+ com_btn.node.on(Node.EventType.TOUCH_START, com_btn[touch_start]);
333
+ }
334
+ touch_start = 'CALL_TOUCH_MOVE'
335
+ if (data.touchMove && !com_btn[touch_start]) {
336
+ com_btn.node.off(Node.EventType.TOUCH_MOVE, com_btn[touch_start]);
337
+ const call_start = (btn) => {
338
+ data.touchMove?.(self, btn)
339
+ }
340
+ com_btn[touch_start] = call_start
341
+ com_btn.node.on(Node.EventType.TOUCH_MOVE, com_btn[touch_start]);
342
+ }
343
+ touch_start = 'CALL_TOUCH_END'
344
+ if (data.touchEnd && !com_btn[touch_start]) {
345
+ com_btn.node.off(Node.EventType.TOUCH_END, com_btn[touch_start]);
346
+ const call_start = (btn) => {
347
+ data.touchEnd?.(self, btn)
348
+ }
349
+ com_btn[touch_start] = call_start
350
+ com_btn.node.on(Node.EventType.TOUCH_END, com_btn[touch_start]);
351
+ }
352
+ touch_start = 'CALL_TOUCH_CANCEL'
353
+ if (data.touchCancel && !com_btn[touch_start]) {
354
+ com_btn.node.off(Node.EventType.TOUCH_CANCEL, com_btn[touch_start]);
355
+ const call_start = (btn) => {
356
+ data.touchCancel?.(self, btn)
357
+ }
358
+ com_btn[touch_start] = call_start
359
+ com_btn.node.on(Node.EventType.TOUCH_CANCEL, com_btn[touch_start]);
321
360
  }
322
- com_btn['btnCall'] = btnCall
323
- com_btn.node.on(Button.EventType.CLICK, com_btn['btnCall']);
324
361
  break;
325
362
  case 'cc.ProgressBar':
326
363
  if (data.reset) {
327
364
  data.reset(self, value, com);
328
365
  } else
329
- if (value) (com as ProgressBar).progress = Number(value) || 0;
366
+ if (value != undefined && value !== null) (com as ProgressBar).progress = Number(value) || 0;
330
367
  break;
331
368
  case 'cc.Skeleton':
332
369
  if (data.reset) {
333
370
  data.reset(self, value, com);
334
371
  } else
335
- if (value) (com as sp.Skeleton).skeletonData = value
372
+ if (value != undefined && value !== null) (com as sp.Skeleton).skeletonData = value
336
373
  break;
337
374
  case 'cc.Slider':
338
- const com_sld = (com as Slider);
339
- if (data.reset) {
340
- data.reset(self, value, com);
341
- } else
342
- if (value) com_sld.progress = Number(value) || 0;
343
-
344
- //事件
345
- com_sld.node.off("slide", com_sld['slideCall'], self)
346
- tempData.skip = true;
347
- const slideCall = (slider) => {
348
- tempData.value = slider.progress
349
- self.viewModel[sx] = tempData
350
- data.event?.(self)
351
- 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
+ }
352
397
  }
353
- com_sld['slideCall'] = slideCall
354
- com_sld.node.on('slide', slideCall, self);
355
398
  break;
356
399
  case 'cc.Toggle':
357
- const com_tg = (com as Toggle);
358
- if (data.reset) {
359
- data.reset(self, value, com);
360
- } else
361
- if (value) com_tg.isChecked = Boolean(value);
362
-
363
- //事件
364
- com_tg.node.off(Toggle.EventType.TOGGLE, com_tg['toggleCall'], self)
365
- tempData.skip = true;
366
- const toggleCall = (toggle) => {
367
- tempData.value = toggle.isChecked
368
- self.viewModel[sx] = tempData
369
- data.event?.(self)
370
- 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
+ }
371
422
  }
372
- com_tg['toggleCall'] = toggleCall
373
- com_tg.node.on(Toggle.EventType.TOGGLE, toggleCall, self);
374
423
  break;
375
424
  case 'cc.EditBox':
376
- const com_eb = (com as EditBox);
377
- if (data.reset) {
378
- data.reset(self, value, com);
379
- } else
380
- if (value) com_eb.string = value?.toString() || '';
381
-
382
- //事件
383
- com_eb.node.off("text-changed", com_eb['ebCall'], self)
384
- tempData.skip = true;
385
- const ebCall = (editbox: EditBox) => {
386
- tempData.value = editbox.textLabel.string
387
- self.viewModel[sx] = tempData
388
- data.event?.(self)
389
- 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
+ }
390
447
  }
391
- com_eb['ebCall'] = ebCall
392
- com_eb.node.on('text-changed', ebCall, self);
393
448
  break;
394
449
  case 'cc.ToggleContainer':
395
450
  {
@@ -400,6 +455,7 @@ function updateStatus(data: IBindingData, com: Component, value: any, self: any)
400
455
 
401
456
  //事件
402
457
  if (com_tgc.checkEvents.length <= 0) {
458
+ const sx = data.propertyKey;
403
459
  const funcName = "onClick_ToggleContainer"
404
460
  const clickEventHandler = new EventHandler();
405
461
  clickEventHandler.target = self.node; // 这个 node 节点是你的事件处理代码组件所属的节点
@@ -430,7 +486,7 @@ function updateStatus(data: IBindingData, com: Component, value: any, self: any)
430
486
  // ✅ 关键:不要缓存 count,而是通过 dataPath 动态取值
431
487
  const getLatestDataLength = () => {
432
488
  const latestValue = self._getNestedValue(self, data.dataPath);
433
- return Array.isArray(latestValue) ? latestValue.length : 0;
489
+ return latestValue ? latestValue.length : 0;
434
490
  };
435
491
 
436
492
  if (com_list.isInit) {
@@ -481,13 +537,21 @@ function updateStatus(data: IBindingData, com: Component, value: any, self: any)
481
537
  // const width = 100
482
538
  // const height = 163
483
539
  // layout.itemSize = math.size(width, height)
484
- table_collection.layout = data.layout()
540
+ table_collection.layout = data.layout(self)
485
541
  // 注册列表内需要使用的 cell 节点类型
486
542
  // 这个演示是通过编辑器绑定的,可以查看场景内 list 节点里的 register cells 配置
487
543
  // this.table_collection.register('cell', () => instantiate('your cell prefab'))
488
544
  // 确定列表内一共需要显示多少条内容
489
545
  // table_collection.isCenterShow = false;//少于宽度,居中显示
490
- 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
+ }
491
555
  table_collection.cellForItemAt = (indexPath, collectionView) => {
492
556
  return data.cellForItemAt(self, indexPath, collectionView as any) // 返回这个节点给列表显示
493
557
  }
@@ -503,8 +567,9 @@ function updateStatus(data: IBindingData, com: Component, value: any, self: any)
503
567
  table_collection.reloadData()
504
568
  }
505
569
  break;
506
- default:
507
- console.error(`请检查类型: ${data.type}`);
570
+ default: {
571
+ if (com) console.error(`请检查类型: ${data.type}`);
572
+ }
508
573
  }
509
574
 
510
575
  }
@@ -516,33 +581,11 @@ function updateStatus(data: IBindingData, com: Component, value: any, self: any)
516
581
  * 响应式数据装饰器
517
582
  * 自动将属性转为响应式对象,并使用属性名作为路径前缀
518
583
  */
519
- export function BindViewModel<T extends new () => any>(constructor: T) {
520
- return function (target: any, propertyKey: string) {
521
- const originalOnLoad = target.constructor.prototype.onLoad;
522
- target.constructor.prototype.onLoad = function () {
523
- // 创建实例并转为响应式
524
- const instance = new constructor();
525
- this[propertyKey] = this._makeReactive(instance, propertyKey);
526
- originalOnLoad?.call(this);
527
- };
528
- };
529
- }
530
584
 
531
585
  // 定义装饰器
532
586
  export function Ref(target: any, propertyKey: string) {
533
-
534
587
  const className = js.getClassName(target)
535
588
  if (!refMap.has(className)) { refMap.set(className, []) }
536
589
  const refList = refMap.get(className)
537
- if (refList.length <= 0) {
538
- const originalOnLoad = target.constructor.prototype.onLoad;
539
- target.constructor.prototype.onLoad = function (this: any) {
540
- this.initReferenceCollector();
541
- this.defineProperty(propertyKey);
542
- originalOnLoad?.call(this);
543
- this.onLoadFinish();
544
- };
545
-
546
- }
547
590
  refList.push(propertyKey)
548
591
  }
@@ -522,6 +522,20 @@ export abstract class YXLayout {
522
522
  * 列表组件销毁时执行
523
523
  */
524
524
  onDestroy() { }
525
+
526
+
527
+ //#region 新加
528
+ /**
529
+ * 转换为真实索引
530
+ * 列表数量大小为 3 倍实际数据数量,需要通过求余方式获取数据,避免数组越界
531
+ */
532
+ dataCount: number = 0
533
+ originIndex(index: number): number {
534
+ return 0
535
+ }
536
+ originIndexCount(): number {
537
+ return this.dataCount * 3
538
+ }
525
539
  }
526
540
 
527
541
  /**
@@ -100,11 +100,18 @@ enum _yx_flow_layout_section_kinds {
100
100
  */
101
101
  export class YXFlowLayout extends YXBinaryLayout {
102
102
 
103
- /**
104
- * 是否开启分页滚动效果
105
- */
106
- pagingEnabled: boolean = false
107
103
 
104
+ // pagingEnabled: boolean = false
105
+ _pagingEnabled: boolean = false
106
+ set pagingEnabled(value: boolean) {
107
+ this._pagingEnabled = value
108
+ }
109
+ /**
110
+ * 是否开启分页滚动效果
111
+ */
112
+ get pagingEnabled() {
113
+ return this._pagingEnabled
114
+ }
108
115
  /**
109
116
  * 分页吸附动画时间
110
117
  */
@@ -119,7 +126,7 @@ export class YXFlowLayout extends YXBinaryLayout {
119
126
  /**
120
127
  * 约束优先级
121
128
  */
122
- priority: _yx_flow_layout_priority = YXFlowLayout.Priority.LEFT
129
+ priority: _yx_flow_layout_priority = YXFlowLayout.Priority.SIDE
123
130
  static Priority = _yx_flow_layout_priority
124
131
 
125
132
  /**
@@ -0,0 +1,100 @@
1
+ import { ScrollView } from "cc";
2
+ import { YXFlowLayout } from "./yx-flow-layout";
3
+ import { YXCollectionView, YXIndexPath } from "./yx-collection-view";
4
+ import { math } from "cc";
5
+
6
+
7
+ export class YXPagelayout extends YXFlowLayout {
8
+
9
+ _pagingEnabledLoop = false
10
+ set pagingEnabledLoop(value: boolean) {
11
+ this._pagingEnabledLoop = value
12
+ }
13
+ get pagingEnabledLoop() {
14
+ return this._pagingEnabledLoop
15
+ }
16
+ /**
17
+ * 记录当前页面
18
+ */
19
+ pageIdx: number = -1
20
+
21
+ collectionView: YXCollectionView
22
+ scrollView: ScrollView;
23
+ dataCount: number = 0
24
+
25
+
26
+ pageAction: (idx: number) => void
27
+ loop(collectionView: YXCollectionView) {
28
+ /**
29
+ * 无限轮播实现思路
30
+ * 列表容器总体大小为 数据条数 * 3 的大小,每次在滚动结束的时候,偏移量总是复位到中间的位置,以此来实现无限滚动
31
+ * 比如原始数据 [ 0,1,2 ],实际上在列表中为 [ 0,1,2, 0,1,2, 0,1,2 ],每次滑动结束之后位置总是复位到中间区域
32
+ */
33
+
34
+ // 注册列表内需要使用的 cell 节点类型
35
+ // 这个演示是通过编辑器绑定的,可以查看场景内 list 节点里的 register cells 配置
36
+ // this.listComp.register(`cell`, () => instantiate('your cell prefab'))
37
+ this.collectionView = collectionView
38
+ this.scrollView = collectionView.scrollView
39
+ this.scrollView.node.on(ScrollView.EventType.SCROLLING, this.checkPageChange, this)
40
+ this.scrollView.node.on(ScrollView.EventType.SCROLL_ENDED, this.resetOffset, this)
41
+ this.pagingEnabled = true;
42
+ this.collectionView.recycleInterval = 0
43
+ }
44
+
45
+ onDestroy(): void {
46
+ this.scrollView.node.off(ScrollView.EventType.SCROLLING, this.checkPageChange, this)
47
+ this.scrollView.node.off(ScrollView.EventType.SCROLL_ENDED, this.resetOffset, this)
48
+ }
49
+
50
+ /**
51
+ * 获取当前页面索引
52
+ * @returns
53
+ */
54
+ getCurrentPageIndex(): number {
55
+ let offset = this.collectionView.scrollView.getScrollOffset()
56
+ offset.x = - offset.x
57
+ let idx = Math.round(offset.x / this.collectionView.scrollView.view.width)
58
+ return idx
59
+ }
60
+
61
+ /**
62
+ * 检查页面变化
63
+ */
64
+ checkPageChange() {
65
+ const idx = this.getCurrentPageIndex()
66
+ if (this.pageIdx !== idx) {
67
+ this.pageIdx = idx
68
+ // 走到这里表示页面发生变化,可以处理需要处理的逻辑
69
+ this.pageAction && this.pageAction(this.originIndex(this.pageIdx))
70
+ console.log(this.originIndex(this.pageIdx));
71
+
72
+ }
73
+ }
74
+
75
+ /**
76
+ * 使列表复位到中间区域
77
+ */
78
+ resetOffset() {
79
+ let offset = this.scrollView.getScrollOffset()
80
+ offset.x = - offset.x
81
+ let idx = Math.round(offset.x / this.scrollView.view.width) % this.dataCount
82
+ offset.x = this.scrollView.view.width * (this.dataCount + idx)
83
+ this.scrollView.scrollToOffset(offset)
84
+ // 直接设置滚动位置不会触发刷新,这里强制刷新一下
85
+ this.collectionView.markForUpdateVisibleData(true)
86
+ }
87
+
88
+ /**
89
+ * 转换为真实索引
90
+ * 列表数量大小为 3 倍实际数据数量,需要通过求余方式获取数据,避免数组越界
91
+ */
92
+ originIndex(index: number): number {
93
+ return index % this.dataCount
94
+ }
95
+ originIndexCount(): number {
96
+ return this.dataCount * 3
97
+ }
98
+ }
99
+
100
+
@@ -0,0 +1,9 @@
1
+ {
2
+ "ver": "4.0.24",
3
+ "importer": "typescript",
4
+ "imported": true,
5
+ "uuid": "b0ea1fb4-0c5b-4be8-8e3b-11a9dc7f1a10",
6
+ "files": [],
7
+ "subMetas": {},
8
+ "userData": {}
9
+ }
@@ -82,7 +82,7 @@ export class scroll_config {
82
82
  })
83
83
  cellSpaceRight: number = 20
84
84
 
85
- @property({ displayName: `整页滚动>>>>` })
85
+ @property({ displayName: `整页滚动`, tooltip: `需要设置左右间距:总宽ContentSize/2-cell宽/2` })
86
86
  isPage: boolean = false
87
87
 
88
88
  @property({
@@ -28,7 +28,7 @@ export class ListViewPage extends ListView {
28
28
  this.node.on(ScrollView.EventType.SCROLL_BEGAN, this.onTouchStart, this);
29
29
  this.node.on(ScrollView.EventType.TOUCH_UP, this.onTouchEnd, this);
30
30
  this.node.on(ScrollView.EventType.SCROLLING, this._scrollViewDidScroll, this);
31
- this.node.on(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
31
+ this.node.on(Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
32
32
 
33
33
  //ScrollView.EventType
34
34
  }
@@ -83,7 +83,9 @@ export class ListViewPage extends ListView {
83
83
  this.content = content
84
84
  viewMask.getComponent(Widget).updateAlignment()
85
85
  }
86
+
86
87
  this.contentUT = this.content.getComponent(UITransform)
88
+ let count = 0
87
89
  if (this.config.scrollDirection === collection_view_scroll_direction.HORIZONTAL) {
88
90
  this.contentUT.anchorX = this.config.isLoop ? 0.5 : 0
89
91
  this.contentUT.anchorY = 0.5
@@ -91,10 +93,13 @@ export class ListViewPage extends ListView {
91
93
  this.contentUT.anchorX = 0.5
92
94
  this.contentUT.anchorY = this.config.isLoop ? 0.5 : 1
93
95
  }
96
+
94
97
  this.nodeUT.setAnchorPoint(0.5, 0.5)
95
98
  const mask_node = this.content.parent.getComponent(UITransform)
96
99
  this.contentUT.contentSize = new Size(mask_node.width, mask_node.height)
97
100
  this.scrollTo(v2(0))
101
+
102
+
98
103
  }
99
104
  initView() {
100
105
  if (this.config.scrollDirection === collection_view_scroll_direction.HORIZONTAL) {
@@ -119,7 +124,7 @@ export class ListViewPage extends ListView {
119
124
  this.node.off(Node.EventType.TOUCH_START, this.onTouchStart, this);
120
125
  this.node.off(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
121
126
  this.node.off(Node.EventType.TOUCH_END, this.onTouchEnd, this);
122
- this.node.off(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
127
+ this.node.off(Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
123
128
 
124
129
  }
125
130
 
@@ -208,6 +213,7 @@ export class ListViewPage extends ListView {
208
213
 
209
214
 
210
215
  _reloadData() {
216
+ this.stopAutoScroll()
211
217
  let numberOfItems = this.delegate.numberOfItems();
212
218
  this.numberOfItems = numberOfItems;
213
219
 
@@ -235,7 +241,7 @@ export class ListViewPage extends ListView {
235
241
  }
236
242
  let offsetMax = this.getMaxScrollOffset();
237
243
 
238
- this.stopAutoScroll()
244
+
239
245
 
240
246
  this.scrollToOffset(v2(-offset.x, offset.y))
241
247
  this.isReload = true;
@@ -296,6 +302,7 @@ export class ListViewPage extends ListView {
296
302
  start_pos = this.getShowRowListPos()
297
303
 
298
304
  this.visbleCellList.forEach((cell, index) => {
305
+ console.log(`cell.row:${cell.row_data},${cell.row}`)
299
306
  let x = 0;
300
307
  if (lastCell) {
301
308
  if (this.config.scrollDirection === collection_view_scroll_direction.HORIZONTAL) {
@@ -358,27 +365,40 @@ export class ListViewPage extends ListView {
358
365
  target_pos = v3(0, 0, 0)
359
366
  currentRow = 0
360
367
  }
368
+
361
369
  const count = Math.max(showChount - (showChount - currentRow), 0);
362
370
 
363
371
  const width = this.getWidth() + this.config.cellSpace;
364
372
  const max_height = width * count
365
373
  let start = 0
366
374
  if (this.config.scrollDirection === collection_view_scroll_direction.HORIZONTAL) {
367
- start = (target_pos.x - max_height)
368
- if (start <= 0) {
369
- start = start + this.getWidth() * 0.5
375
+ if (target_pos) {
376
+
377
+ start = (target_pos.x - max_height)
378
+ // if (max_height === 0) { start = 0 }
379
+ if (start <= 0) {
380
+ start = start + this.getWidth() * 0.5
381
+ }
382
+ if (this.lastCellCount <= 0) {
383
+ start += this.config.cellSpaceLeft
384
+ }
370
385
  }
371
- if (this.lastCellCount <= 0) {
372
- start += this.config.cellSpaceLeft
386
+ else {
387
+ start += this.config.cellSpaceLeft + this.getWidth() * 0.5
373
388
  }
374
389
  } else {
375
- start = (target_pos.y + max_height)
376
- if (start >= 0) {
377
- start = start - this.getWidth() * 0.5
378
- }
379
- if (this.lastCellCount <= 0) {
380
- start -= this.config.cellSpaceLeft
390
+ if (target_pos) {
391
+ start = (target_pos.y + max_height)
392
+ if (start >= 0) {
393
+ start = start - this.getWidth() * 0.5
394
+ }
395
+ if (this.lastCellCount <= 0) {
396
+ start -= this.config.cellSpaceLeft
397
+ }
398
+ } else {
399
+ start += this.config.cellSpaceLeft + this.getWidth() * 0.5
381
400
  }
401
+
382
402
  }
383
403
 
384
404
  return start
@@ -392,13 +412,12 @@ export class ListViewPage extends ListView {
392
412
  const count_n = this.numberOfItems - this.max_row_data;
393
413
  let row = count_n > 0 ? this.min_row_data : Math.max(this.min_row_data - (-count_n + 1), 0)
394
414
  if (this.visbleCellList.length > 0) {
395
- if (this.numberOfItems > this.config.maxShowCount &&
396
- this.currentRow < this.numberOfItems - 1 &&
397
- this.max_row_data + 1 < this.numberOfItems &&
415
+ const ok_1 = this.numberOfItems > this.config.maxShowCount
416
+ const ok_2 = this.currentRow < this.numberOfItems - 1
417
+ const ok_3 = this.max_row_data + 1 < this.numberOfItems
418
+ const ok_4 = (this.currentRow === this.visbleCellList[this.visbleCellList.length - 1].row_data || this.currentRow === this.visbleCellList[this.visbleCellList.length - 2].row_data)
398
419
 
399
- (this.currentRow === this.visbleCellList[this.visbleCellList.length - 1].row_data ||
400
- this.currentRow === this.visbleCellList[this.visbleCellList.length - 2].row_data)
401
- ) {
420
+ if (ok_1 && ok_2 && ok_3 && ok_4 && row != 0) {
402
421
  row += 1;
403
422
  this.max_row_data += 1
404
423
  //console.error("走了", this.max_row_data)
@@ -457,6 +476,22 @@ export class ListViewPage extends ListView {
457
476
  this.touchEnd(event, false)
458
477
  }
459
478
 
479
+ }
480
+ onTouchCancel(event: EventTouch) {
481
+
482
+ if (this.config.isPage)
483
+ this.onTouchEnd(event)
484
+
485
+ // const of = this.getScrollOffset()
486
+ // if (this.config.scrollDirection === collection_view_scroll_direction.HORIZONTAL) {
487
+ // if (of.x < 0)
488
+ // this.onTouchEnd(event)
489
+ // } else {
490
+ // if (of.x < 0)
491
+ // this.onTouchEnd(event)
492
+ // }
493
+
494
+
460
495
  }
461
496
 
462
497
  touchEnd(event: EventTouch, isInit) {
@@ -637,6 +672,7 @@ export class ListViewPage extends ListView {
637
672
  _scrollViewDidScrollPage(is_move = false) {
638
673
  this._updateMaxNode()
639
674
  const of = this.getScrollOffset();
675
+ // console.log(of)
640
676
  if (this.config.scrollDirection === collection_view_scroll_direction.HORIZONTAL) {
641
677
  this.velocity = Math.abs((of.x - this.lastOffset.x))
642
678
  } else {
@@ -584,7 +584,7 @@ export class ListViewPageLoop extends ListView {
584
584
  this.currentRow = this.maxNode.row_data;
585
585
 
586
586
  } else {
587
- console.error("没有")
587
+ //console.error("没有")
588
588
  }
589
589
  }
590
590
  _scrollViewDidScrollPage(is_move: boolean = false) {
@@ -33,29 +33,49 @@ export class TableView extends Component {
33
33
  return this.delegate ? true : false;
34
34
  }
35
35
  finish: Function;
36
+ isOnload = false;
36
37
  // view: Node;
37
38
  protected onLoad(): void {
38
39
  if (this.config.isLoop) {
39
40
  this.scrollView = this.node.addComponent(ListViewPageLoop)
41
+ this.scrollView.elastic = false
40
42
  } else {
41
43
  this.scrollView = this.node.addComponent(ListViewPage)
44
+ this.scrollView.elastic = this.config.isPage ? false : true
42
45
  }
43
46
  this.scrollView.elastic = false
47
+
44
48
  this.scrollView.delegate = this.delegate;
45
49
  this.scrollView.config = this.config;
46
50
  this.scrollView.init();
47
- this.finish?.()
51
+ this.isOnload = true
52
+ if (this.finish) {
53
+ this.finish()
54
+ }
55
+
48
56
  }
49
57
  init(delegate: IListView) {
50
58
  this.delegate = delegate
51
59
  //解决一些设置时间点慢的问题
52
60
  if (this.scrollView) {
53
61
  this.scrollView.delegate = delegate
62
+ const itemSize = this.delegate.itemSize();
63
+ let count = 0
64
+ if (this.config.scrollDirection === collection_view_scroll_direction.HORIZONTAL) {
65
+ count = this.scrollView.nodeUT.width / (itemSize.width + this.config.cellSpace)//+ this.config.cellSpaceLeft + this.config.cellSpaceRight
66
+ } else {
67
+ count = this.scrollView.nodeUT.height / (itemSize.height + this.config.cellSpace)//+ this.config.cellSpaceLeft + this.config.cellSpaceRight
68
+ }
69
+ this.config.maxShowCount = Math.max(Math.floor(count) + 3, this.config.maxShowCount)
70
+ console.log("maxShowCount", this.config.maxShowCount)
54
71
  }
55
-
56
72
  }
57
73
  onLoadFinish(call: () => void) {
58
74
  this.finish = call
75
+ if (this.isOnload) {
76
+ this.finish?.()
77
+ this.finish = null
78
+ }
59
79
  }
60
80
 
61
81
  public reload() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cc-component/cc-ex-component",
3
- "version": "1.2.7",
3
+ "version": "1.2.9",
4
4
  "engine": ">=3.8.6",
5
5
  "description": "系统组件添加常用扩展方法",
6
6
  "main": "index.ts",