鸿蒙HarmonyOS实战-ArkTS语言(渲染控制)_function return type inference is limited (arkts-n

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!


img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以戳这里获取

分支控制: 在程序执行过程中,有时需要根据不同的条件分支来执行不同的代码逻辑。if/else结构通过判断条件来决定程序如何执行,实现了程序的分支控制。

数据迭代: 在程序中,需要对一些数据进行遍历、操作或者计算。ForEach和LazyForEach提供了一种便捷的方法,可以针对数据集合进行遍历,并对其中的每个元素执行特定操作。

惰性计算: 在某些情况下,程序中需要对大量的数据进行遍历或计算。LazyForEach可以实现惰性计算,只在需要时才计算相应的结果,避免了程序在运行时不必要的计算,从而提高程序效率。

一、ArkTS语言渲染控制

ArkTS是一种基于TypeScript的编程语言,支持对渲染过程进行控制和调整。以下是ArkTS语言中实现渲染控制的三个关键组件:

  1. if/else:if/else结构可以用于根据条件控制是否渲染某些元素。例如,可以通过if/else语句来实现某些物体在特定场景或条件下的显示或隐藏。
  2. ForEach:ForEach是一个迭代方法,能够遍历数组、对象等数据结构中的元素,并在渲染过程中对它们进行控制。例如,可以使用ForEach在场景中定位并控制多个物体的位置、尺寸、颜色等属性。
  3. LazyForEach:与普通ForEach不同,LazyForEach是一个惰性迭代方法,它只在需要迭代数据时才进行计算。这使得LazyForEach在处理大型数据集时更加高效,可以减少渲染时间和资源占用。

通过这些关键组件,ArkTS语言可以实现灵活、高效的渲染控制,帮助开发人员实现各种复杂的渲染效果和场景呈现。

1.if/else:条件渲染

1.1 变化规则

If/else是一种在程序中用于控制流程的结构。它包括一个if语句和一个可选的else语句。if语句表示如果条件成立,那么就执行一段代码,否则跳过该代码;else语句表示如果条件不成立,那么就执行另一段代码。这种结构允许程序根据不同的条件执行不同的操作,从而实现更灵活的程序控制。

1.2 使用场景
1.2.1 使用if进行条件渲染

@Entry
@Component
struct ViewA {
@State count: number = 0;

build() {
Column() {
Text(count=${this.count})

if (this.count > 0) {
Text(count is positive)
.fontColor(Color.Green)
}

Button(‘increase count’)
.onClick(() => {
this.count++;
})
Button(‘decrease count’)
.onClick(() => {
this.count–;
})
}
}
}

1.2.2 使用if/else进行条件渲染

@Component
struct CounterView {
@Link counter: number;
label: string = ‘unknown’;

build() {
Row() {
Text(${this.label})
Button(counter ${this.counter} +1)
.onClick(() => {
this.counter += 1;
})
}
}
}
@Entry
@Component
struct MainView {
@State toggle: boolean = true;
@State counter: number = 0;
build() {
Column() {
if (this.toggle) {
CounterView({ counter: $counter, label: ‘CounterView #positive’ })
} else {
CounterView({ counter: $counter, label: ‘CounterView #negative’ })
}
Button(toggle ${this.toggle})
.onClick(() => {
this.toggle = !this.toggle;
})
}
}
}

1.2.3 嵌套if语句

@Entry
@Component
struct CompA {
@State toggle: boolean = false;
@State toggleColor: boolean = false;

build() {
Column() {
Text(‘Before’)
.fontSize(15)
if (this.toggle) {
Text(‘Top True, positive 1 top’)
.backgroundColor(‘#aaffaa’).fontSize(20)
// 内部if语句
if (this.toggleColor) {
Text(‘Top True, Nested True, positive COLOR Nested ‘)
.backgroundColor(’#00aaaa’).fontSize(15)
} else {
Text(‘Top True, Nested False, Negative COLOR Nested ‘)
.backgroundColor(’#aaaaff’).fontSize(15)
}
} else {
Text(‘Top false, negative top level’).fontSize(20)
.backgroundColor(‘#ffaaaa’)
if (this.toggleColor) {
Text(‘positive COLOR Nested ‘)
.backgroundColor(’#00aaaa’).fontSize(15)
} else {
Text(‘Negative COLOR Nested ‘)
.backgroundColor(’#aaaaff’).fontSize(15)
}
}
Text(‘After’)
.fontSize(15)
Button(‘Toggle Outer’)
.onClick(() => {
this.toggle = !this.toggle;
})
Button(‘Toggle Inner’)
.onClick(() => {
this.toggleColor = !this.toggleColor;
})
}
}
}

2.ForEach:循环渲染

2.1 变化规则

ForEach是一个数组方法,用于执行一些操作,例如对数组中的每个元素执行一些代码,或者将每个元素转换为新的数组。它可以接收一个回调函数作为参数,该函数将在数组的每个元素上执行一次。在每次调用回调函数时,都会向其传递当前元素的值、索引和整个数组。该方法不会更改原始数组,而是返回一个新的、由回调函数返回的数组。

ForEach接口描述:

ForEach(
arr: Array,
itemGenerator: (item: Array, index?: number) => void,
keyGenerator?: (item: Array, index?: number): string => string
)

注意点keyGenerator为键值生成函数,可以达到去重的效果:
在这里插入图片描述

@Entry
@Component
struct Parent {
@State simpleList: Array = [‘one’, ‘two’, ‘two’, ‘three’];

build() {
Row() {
Column() {
ForEach(this.simpleList, (item: string) => {
ChildItem({ item: item })
}, (item: string) => item)
}
.width(‘100%’)
.height(‘100%’)
}
.height(‘100%’)
.backgroundColor(0xF1F3F5)
}
}
@Component
struct ChildItem {
@Prop item: string;
build() {
Text(this.item)
.fontSize(50)
}
}

执行结果
在这里插入图片描述

2.2 使用场景
2.2.1 数据源不变

@Entry
@Component
struct ArticleList {
@State simpleList: Array = [1, 2, 3, 4, 5];

build() {
Column() {
ForEach(this.simpleList, (item: string) => {
ArticleSkeletonView()
.margin({ top: 20 })
}, (item: string) => item)
}
.padding(20)
.width(‘100%’)
.height(‘100%’)
}
}
@Builder
function textArea(width: number | Resource | string = ‘100%’, height: number | Resource | string = ‘100%’) {
Row()
.width(width)
.height(height)
.backgroundColor(‘#FFF2F3F4’)
}
@Component
struct ArticleSkeletonView {
build() {
Row() {
Column() {
textArea(80, 80)
}
.margin({ right: 20 })
Column() {
textArea(‘60%’, 20)
textArea(‘50%’, 20)
}
.alignItems(HorizontalAlign.Start)
.justifyContent(FlexAlign.SpaceAround)
.height(‘100%’)
}
.padding(20)
.borderRadius(12)
.backgroundColor(‘#FFECECEC’)
.height(120)
.width(‘100%’)
.justifyContent(FlexAlign.SpaceBetween)
}
}

执行效果:
在这里插入图片描述

2.2.2 数据源数组项发生变化

@Entry
@Component
struct ArticleListView {
@State isListReachEnd: boolean = false;
@State articleList: Array

= [
new Article(‘001’, ‘第1篇文章’, ‘文章简介内容’),
new Article(‘002’, ‘第2篇文章’, ‘文章简介内容’),
new Article(‘003’, ‘第3篇文章’, ‘文章简介内容’),
new Article(‘004’, ‘第4篇文章’, ‘文章简介内容’),
new Article(‘005’, ‘第5篇文章’, ‘文章简介内容’),
new Article(‘006’, ‘第6篇文章’, ‘文章简介内容’)
]

loadMoreArticles() {
this.articleList.push(new Article(‘007’, ‘加载的新文章’, ‘文章简介内容’));
}

build() {
Column({ space: 5 }) {
List() {
ForEach(this.articleList, (item: Article) => {
ListItem() {
ArticleCard({ article: item })
.margin({ top: 20 })
}
}, (item: Article) => item.id)
}
.onReachEnd(() => {
this.isListReachEnd = true;
})
.parallelGesture(
PanGesture({ direction: PanDirection.Up, distance: 80 })
.onActionStart(() => {
if (this.isListReachEnd) {
this.loadMoreArticles();
this.isListReachEnd = false;
}
})
)
.padding(20)
.scrollBar(BarState.Off)
}
.width(‘100%’)
.height(‘100%’)
.backgroundColor(0xF1F3F5)
}
}
@Component
struct ArticleCard {
@Prop article: Article;
build() {
Row() {
Image($r(‘app.media.icon’))
.width(80)
.height(80)
.margin({ right: 20 })
Column() {
Text(this.article.title)
.fontSize(20)
.margin({ bottom: 8 })
Text(this.article.brief)
.fontSize(16)
.fontColor(Color.Gray)
.margin({ bottom: 8 })
}
.alignItems(HorizontalAlign.Start)
.width(‘80%’)
.height(‘100%’)
}
.padding(20)
.borderRadius(12)
.backgroundColor(‘#FFECECEC’)
.height(120)
.width(‘100%’)
.justifyContent(FlexAlign.SpaceBetween)
}
}

当列表滚动到底部时,如果手势滑动距离超过指定的80,将触发loadMoreArticle()函数。此函数会在articleList数据源的尾部添加一个新的数据项,从而增加数据源的长度。

执行效果:
在这里插入图片描述

2.2.3 数据源数组项子属性变化

@Entry
@Component
struct ArticleListView {
@State articleList: Array

= [
new Article(‘001’, ‘第0篇文章’, ‘文章简介内容’, false, 100),
new Article(‘002’, ‘第1篇文章’, ‘文章简介内容’, false, 100),
new Article(‘003’, ‘第2篇文章’, ‘文章简介内容’, false, 100),
new Article(‘004’, ‘第4篇文章’, ‘文章简介内容’, false, 100),
new Article(‘005’, ‘第5篇文章’, ‘文章简介内容’, false, 100),
new Article(‘006’, ‘第6篇文章’, ‘文章简介内容’, false, 100),
];

build() {
List() {
ForEach(this.articleList, (item: Article) => {
ListItem() {
ArticleCard({
article: item
})
.margin({ top: 20 })
}
}, (item: Article) => item.id)
}
.padding(20)
.scrollBar(BarState.Off)
.backgroundColor(0xF1F3F5)
}
}
@Component
struct ArticleCard {
@ObjectLink article: Article;
handleLiked() {
this.article.isLiked = !this.article.isLiked;
this.article.likesCount = this.article.isLiked ? this.article.likesCount + 1 : this.article.likesCount - 1;
}
build() {
Row() {
Image($r(‘app.media.icon’))
.width(80)
.height(80)
.margin({ right: 20 })
Column() {
Text(this.article.title)
.fontSize(20)
.margin({ bottom: 8 })
Text(this.article.brief)
.fontSize(16)
.fontColor(Color.Gray)
.margin({ bottom: 8 })
Row() {
Image(this.article.isLiked ? $r(‘app.media.iconLiked’) : $r(‘app.media.iconUnLiked’))
.width(24)
.height(24)
.margin({ right: 8 })
Text(this.article.likesCount.toString())
.fontSize(16)
}
.onClick(() => this.handleLiked())
.justifyContent(FlexAlign.Center)
}
.alignItems(HorizontalAlign.Start)
.width(‘80%’)
.height(‘100%’)
}
.padding(20)
.borderRadius(12)
.backgroundColor(‘#FFECECEC’)
.height(120)
.width(‘100%’)
.justifyContent(FlexAlign.SpaceBetween)
}
}

执行结果:
在这里插入图片描述
== 注意:开发者在使用ForEach时应特别重视keyGenerator为键值生成函数,会根据键值生成函数确定替换的值。==

3.LazyForEach:数据懒加载

3.1 变化规则

LazyForEach是一种延迟执行的迭代方法,它可以帮助我们更高效地遍历和操作数组。与常规的ForEach方法不同,LazyForEach方法不会立即执行回调函数,而是在需要访问数组元素时才将回调函数应用于该元素。这种延迟执行的方式可以大大减少不必要的计算,提高代码性能。LazyForEach在处理大型数组或频繁进行迭代时特别有用。

LazyForEach接口描述:

LazyForEach(
dataSource: IDataSource, // 需要进行数据迭代的数据源
itemGenerator: (item: any, index?: number) => void, // 子组件生成函数
keyGenerator?: (item: any, index?: number) => string // 键值生成函数
): void

IDataSource接口描述:

interface IDataSource {
totalCount(): number; // 获得数据总数
getData(index: number): Object; // 获取索引值对应的数据
registerDataChangeListener(listener: DataChangeListener): void; // 注册数据改变的监听器
unregisterDataChangeListener(listener: DataChangeListener): void; // 注销数据改变的监听器
}

DataChangeListener接口描述:

interface DataChangeListener {
onDataReloaded(): void; // 重新加载数据时调用
onDataAdded(index: number): void; // 添加数据时调用
onDataMoved(from: number, to: number): void; // 数据移动起始位置与数据移动目标位置交换时调用
onDataDeleted(index: number): void; // 删除数据时调用
onDataChanged(index: number): void; // 改变数据时调用
onDataAdd(index: number): void; // 添加数据时调用
onDataMove(from: number, to: number): void; // 数据移动起始位置与数据移动目标位置交换时调用
onDataDelete(index: number): void; // 删除数据时调用
onDataChange(index: number): void; // 改变数据时调用
}

3.2 使用场景
3.2.1 首次渲染
3.2.1.1 生成不同键值

1、正常渲染

// Basic implementation of IDataSource to handle data listener
class BasicDataSource implements IDataSource {
private listeners: DataChangeListener[] = [];
private originDataArray: string[] = [];

public totalCount(): number {
return 0;
}

public getData(index: number): string {
return this.originDataArray[index];
}

// 该方法为框架侧调用,为LazyForEach组件向其数据源处添加listener监听
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
console.info(‘add listener’);
this.listeners.push(listener);
}
}

// 该方法为框架侧调用,为对应的LazyForEach组件在数据源处去除listener监听
unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
console.info(‘remove listener’);
this.listeners.splice(pos, 1);
}
}

// 通知LazyForEach组件需要重载所有子组件
notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded();
})
}

// 通知LazyForEach组件需要在index对应索引处添加子组件
notifyDataAdd(index: number): void {
this.listeners.forEach(listener => {
listener.onDataAdd(index);
})
}

// 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件
notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index);
})
}

// 通知LazyForEach组件需要在index对应索引处删除该子组件
notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
})
}
}

class MyDataSource extends BasicDataSource {
private dataArray: string[] = [];

public totalCount(): number {
return this.dataArray.length;
}

public getData(index: number): string {
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();

aboutToAppear() {
for (let i = 0; i <= 20; i++) {
this.data.pushData(Hello ${i})
}
}

build() {
List({ space: 3 }) {
LazyForEach(this.data, (item: string) => {
ListItem() {
Row() {
Text(item).fontSize(50)
.onAppear(() => {
console.info(“appear:” + item)
})
}.margin({ left: 10, right: 10 })
}
}, (item: string) => item)
}.cachedCount(5)
}
}

2、键值相同时错误渲染

class BasicDataSource implements IDataSource {
private listeners: DataChangeListener[] = [];
private originDataArray: string[] = [];

public totalCount(): number {
return 0;
}

public getData(index: number): string {
return this.originDataArray[index];
}

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.onDataAdd(index);
})
}

notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index);
})
}

notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
})
}
}

class MyDataSource extends BasicDataSource {
private dataArray: string[] = [];

public totalCount(): number {
return this.dataArray.length;
}

public getData(index: number): string {
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();

aboutToAppear() {
for (let i = 0; i <= 20; i++) {
this.data.pushData(Hello ${i})
}
}

build() {
List({ space: 3 }) {
LazyForEach(this.data, (item: string) => {
ListItem() {
Row() {
Text(item).fontSize(50)
.onAppear(() => {
console.info(“appear:” + item)
})
}.margin({ left: 10, right: 10 })
}
}, (item: string) => ‘same key’)
}.cachedCount(5)
}
}

3.2.2 非首次渲染
3.2.2.1 添加数据

class BasicDataSource implements IDataSource {
private listeners: DataChangeListener[] = [];
private originDataArray: string[] = [];

public totalCount(): number {
return 0;
}

public getData(index: number): string {
return this.originDataArray[index];
}

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.onDataAdd(index);
})
}

notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index);
})
}

notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
})
}
}

class MyDataSource extends BasicDataSource {
private dataArray: string[] = [];

public totalCount(): number {
return this.dataArray.length;
}

public getData(index: number): string {
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();

aboutToAppear() {
for (let i = 0; i <= 20; i++) {
this.data.pushData(Hello ${i})
}
}

build() {
List({ space: 3 }) {
LazyForEach(this.data, (item: string) => {
ListItem() {
Row() {
Text(item).fontSize(50)
.onAppear(() => {
console.info(“appear:” + item)
})
}.margin({ left: 10, right: 10 })
}
.onClick(() => {
// 点击追加子组件
this.data.pushData(Hello ${this.data.totalCount()});
})
}, (item: string) => item)
}.cachedCount(5)
}
}

3.2.2.2 删除数据

class BasicDataSource implements IDataSource {
private listeners: DataChangeListener[] = [];
private originDataArray: string[] = [];

public totalCount(): number {
return 0;
}

public getData(index: number): string {
return this.originDataArray[index];
}

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.onDataAdd(index);
})
}

notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index);
})
}

notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
})
}
}

class MyDataSource extends BasicDataSource {
dataArray: string[] = [];

public totalCount(): number {
return this.dataArray.length;
}

public getData(index: number): string {
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);
}

public deleteData(index: number): void {
this.dataArray.splice(index, 1);
this.notifyDataDelete(index);
}
}

@Entry
@Component
struct MyComponent {
private data: MyDataSource = new MyDataSource();

aboutToAppear() {
for (let i = 0; i <= 20; i++) {
this.data.pushData(Hello ${i})
}
}

build() {
List({ space: 3 }) {
LazyForEach(this.data, (item: string, index: number) => {
ListItem() {
Row() {
Text(item).fontSize(50)
.onAppear(() => {
console.info(“appear:” + item)
})
}.margin({ left: 10, right: 10 })
}
.onClick(() => {
// 点击删除子组件
this.data.deleteData(this.data.dataArray.indexOf(item));
})
}, (item: string) => item)
}.cachedCount(5)
}
}

3.2.2.3 改变单个数据

class BasicDataSource implements IDataSource {
private listeners: DataChangeListener[] = [];
private originDataArray: string[] = [];

public totalCount(): number {
return 0;
}

public getData(index: number): string {
return this.originDataArray[index];
}

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.onDataAdd(index);
})
}

notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index);
})
}

notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
})
}
}

class MyDataSource extends BasicDataSource {
private dataArray: string[] = [];

public totalCount(): number {
return this.dataArray.length;
}

public getData(index: number): string {
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);
}

public deleteData(index: number): void {
this.dataArray.splice(index, 1);
this.notifyDataDelete(index);
}

public changeData(index: number, data: string): void {

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
})
}
}

class MyDataSource extends BasicDataSource {
private dataArray: string[] = [];

public totalCount(): number {
return this.dataArray.length;
}

public getData(index: number): string {
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);
}

public deleteData(index: number): void {
this.dataArray.splice(index, 1);
this.notifyDataDelete(index);
}

public changeData(index: number, data: string): void {

[外链图片转存中…(img-9n1da9W0-1715512402971)]
[外链图片转存中…(img-BuZJLzKY-1715512402972)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值