开源鸿蒙 LazyForEach
LazyForEach
The development framework provides LazyForEach to iterate data from provided data sources and create corresponding components during each iteration. LazyForEach is defined as follows:
LazyForEach(
dataSource: IDataSource, // Data source to be iterated
itemGenerator: (item: any) => void, // child component generator
keyGenerator?: (item: any) => string // (optional) Unique key generator, which is recommended.
): void
interface IDataSource {
totalCount(): number; // Get total count of data
getData(index: number): any; // Get single data by index
registerDataChangeListener(listener: DataChangeListener): void; // Register listener to listening data changes
unregisterDataChangeListener(listener: DataChangeListener): void; // Unregister listener
}
interface DataChangeListener {
onDataReloaded(): void; // Called while data reloaded
onDataAdded(index: number): void; // Called while single data added
onDataMoved(from: number, to: number): void; // Called while single data moved
onDataDeleted(index: number): void; // Called while single data deleted
onDataChanged(index: number): void; // Called while single data changed
}
APIs
LazyForEach
LazyForEach(dataSource: IDataSource, itemGenerator: (item: any) => void, keyGenerator?: (item: any) => string):void
Table1 Parameters
Name | Type | Mandatory | Default Value | Description |
---|---|---|---|---|
dataSource | IDataSource | Yes | - | Object used to implement the IDataSource API. You need to implement related APIs. |
itemGenerator | (item: any) => void | Yes | - | Used to generate the lambda function of the child components. It generates one or more child components for a given array item. A single component and its child component list must be contained in the braces ({…}) |
keyGenerator | (item: any) => string | No | - | Used as an anonymous parameter for generating a unique and stable key value for a given array item. When the position of a subitem in the array is changed, the key value of the subitem cannot be changed. When a subitem in the array is replaced with a new item, the key value of the current item must be different from that of the new item. This key-value generator is optional. However, for performance reasons, it is strongly recommended that the key-value generator be provided, so that the development framework can better identify array changes. If the array is reversed while no key-value generator is provided, all nodes in LazyForEach will be rebuilt. |
Table2 Description of IDataSource
Name | Description |
---|---|
totalCount(): number | Obtains the total number of data records. |
getData(index: number): any | Obtains the data corresponding to the specified index. |
registerDataChangeListener(listener: DataChangeListener): void | Registers the data change listener. |
unregisterDataChangeListener(listener: DataChangeListener): void | Unregisters the data change listener. |
Table3 Description of DataChangeListener
| Name | Description | | ——– | ——– | | onDataReloaded(): void | Reloads all data. | | onDataAdded(index: number): void | Notifies the component that data is added to the position indicated by the specified index. | | onDataMoved(from: number, to: number): void | Notifies the component that data is moved from the from position to the to position. | | onDataDeleted(index: number): void | Notifies the component that data is deleted from the position indicated by the specified index. | | onDataChanged(index: number): void | Notifies the component that data in the position indicated by the specified index is changed. |
NOTE: - LazyForEach must be used in the container component. Only the <List>, <Grid>, and <Swiper> components support LazyForEach (that is, only the visible part and a small amount of data before and after the visible part are loaded for caching). For other components, all data is loaded at a time.
LazyForEach must create one and only one child component in each iteration.
The generated child component must be in the parent container component of LazyForEach.
LazyForEach can be included in an if/else conditional statement, but cannot contain an if/else conditional statement.
For the purpose of high-performance rendering, when the onDataChanged method of the DataChangeListener object is used to update the UI, the component update is triggered only when the state variable is used in the component specified in the UI description of itemGenerator.
The calling sequence of the subitem generator function may be different from that of the data items in the data source. During the development, do not assume whether the subitem generator and key value generator functions are executed and the execution sequence. The following is an example of incorrect usage:
> LazyForEach(dataSource, item => {Text(`${++counter}. item.label`)}) > ``` > > Below is an example of correct usage: > > > ``` > LazyForEach(dataSource, > item => Text(`${item.i}. item.data.label`)), > item => item.data.id.toString()) > ``` ## Example
// Basic implementation of IDataSource to handle data listener class BasicDataSource implements IDataSource { private listeners: DataChangeListener[] = []
public totalCount(): number {
return 0
}
public getData(index: number): any {
return undefined
}
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
console.info('add listener')
this.listeners.push(listener)
}
}
unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
console.info('remove listener')
this.listeners.splice(pos, 1)
}
}
notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded()
})
}
notifyDataAdd(index: number): void {
this.listeners.forEach(listener => {
listener.onDataAdded(index)
})
}
notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChanged(index)
})
}
notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDeleted(index)
})
}
notifyDataMove(from: number, to: number): void {
this.listeners.forEach(listener => {
listener.onDataMoved(from, to)
})
}
}
class MyDataSource extends BasicDataSource { private dataArray: string[] = [‘/path/image0’, ‘/path/image1’, ‘/path/image2’, ‘/path/image3’]
public totalCount(): number {
return this.dataArray.length
}
public getData(index: number): any {
return this.dataArray[index]
}
public addData(index: number, data: string): void {
this.dataArray.splice(index, 0, data)
this.notifyDataAdd(index)
}
public pushData(data: string): void {
this.dataArray.push(data)
this.notifyDataAdd(this.dataArray.length - 1)
}
}
@Entry @Component struct MyComponent { private data: MyDataSource = new MyDataSource() build() { List({space: 3}) { LazyForEach(this.data, (item: string) => { ListItem() { Row() { Image(item).width(“30%”).height(50) Text(item).fontSize(20).margin({left:10}) }.margin({left: 10, right: 10}) } .onClick(()=>{ this.data.pushData(‘/path/image’ + this.data.totalCount()) }) }, item => item) } } } “`
你可能感兴趣的文章
开源鸿蒙 Multi-Language Capability
- 所属分类: 后端技术
- 本文标签:
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦