Feat: some todo ui

This commit is contained in:
cheliangzhao 2023-10-07 17:55:41 +08:00
parent 855412de3c
commit 3765d2b6cf
32 changed files with 243 additions and 31 deletions

View File

@ -1,3 +1,20 @@
# Template # Template
database ## database
注意事项
1. 由于`constructor()`函数不能异步,因此在其中调用`getRdbStore()`
函数时,不能保证新建对象后,数据库初始化完毕。那么此时如果调用`insert`等方法时,`RdbStore`可能还是`undefined`,导致数据库操作失败。
因此,只能使用回调来处理。
```typescript
aboutToAppear() {
this.todoTable.getRdbStore(async () => {
const res = await this.todoTable.query();
this.todoList = res;
})
}
```

View File

@ -1,6 +1,20 @@
{ {
"app": { "app": {
"signingConfigs": [], "signingConfigs": [
{
"name": "default",
"type": "HarmonyOS",
"material": {
"certpath": "C:\\Users\\Administrator\\.ohos\\config\\auto_debug_harmony4-template_com.example.myapplication_70086000144137060.cer",
"storePassword": "0000001BF0C7503EEB99D5360C10359536D3353B1F2C39787692D0526594DC53D8A9103366AB1B58CACBB6",
"keyAlias": "debugKey",
"keyPassword": "0000001BFE46D113BE907F9B0F067070188C870CD7DD7AF4E6CB9720F5CC73389CC6DE77567D43876B55FB",
"profile": "C:\\Users\\Administrator\\.ohos\\config\\auto_debug_harmony4-template_com.example.myapplication_70086000144137060.p7b",
"signAlg": "SHA256withECDSA",
"storeFile": "C:\\Users\\Administrator\\.ohos\\config\\auto_debug_harmony4-template_com.example.myapplication_70086000144137060.p12"
}
}
],
"products": [ "products": [
{ {
"name": "default", "name": "default",

View File

@ -1,10 +1,10 @@
{ {
"license": "",
"devDependencies": {},
"author": "",
"name": "entry", "name": "entry",
"version": "1.0.0",
"description": "Please describe the basic information.", "description": "Please describe the basic information.",
"main": "", "main": "",
"author": "", "version": "1.0.0",
"license": "",
"dependencies": {} "dependencies": {}
} }

View File

@ -1,4 +1,5 @@
import relationalStore from '@ohos.data.relationalStore'; import relationalStore from '@ohos.data.relationalStore';
import { Logger } from '../../utils/Logger';
import { DatabaseConfig } from '../config'; import { DatabaseConfig } from '../config';
export default class Rdb { export default class Rdb {
@ -14,16 +15,17 @@ export default class Rdb {
} }
async getRdbStore(callback) { getRdbStore(callback) {
const context = getContext(this) const context = getContext(this)
try { relationalStore.getRdbStore(context, DatabaseConfig.STORE_CONFIG, (err, store) => {
const store = await relationalStore.getRdbStore(context, DatabaseConfig.STORE_CONFIG) if (err) {
console.error('getRdbStore() failed, error: ' + err)
return
}
this.rdbStore = store; this.rdbStore = store;
console.info('getRdbStore() finished.'); console.info('getRdbStore() finished.');
callback(store) callback(store)
} catch (err) { })
console.error('getRdbStore() failed, error: ' + err)
}
} }
async insertData(data) { async insertData(data) {
@ -55,6 +57,7 @@ export default class Rdb {
try { try {
const rows = await this.rdbStore.delete(predicates); const rows = await this.rdbStore.delete(predicates);
console.info('deleteData() finished: ' + rows); console.info('deleteData() finished: ' + rows);
return rows; return rows;
} catch (err) { } catch (err) {
console.error('deleteData() failed, err: ' + err); console.error('deleteData() failed, err: ' + err);

View File

@ -15,7 +15,7 @@ export default class TodoTable {
this.getRdbStore(callback) this.getRdbStore(callback)
} }
private getRdbStore(callback) { getRdbStore(callback) {
// 假设当前数据库版本为3 // 假设当前数据库版本为3
this.todoTable.getRdbStore(store => { this.todoTable.getRdbStore(store => {
// 当数据库创建时数据库版本默认为0 // 当数据库创建时数据库版本默认为0
@ -35,9 +35,10 @@ export default class TodoTable {
store.executeSql(DatabaseConfig.TODO_TABLE.update2to3); store.executeSql(DatabaseConfig.TODO_TABLE.update2to3);
store.version = 3; store.version = 3;
} }
if (callback) callback()
}) })
if (callback) callback()
} }
async insertData(data: TodoData) { async insertData(data: TodoData) {
@ -59,9 +60,14 @@ export default class TodoTable {
return await this.todoTable.deleteData(predicates); return await this.todoTable.deleteData(predicates);
} }
async query(content: string) { async query(content: string = ''): Promise<TodoData[]> {
const predicates = new relationalStore.RdbPredicates(DatabaseConfig.TODO_TABLE.tableName) const predicates = new relationalStore.RdbPredicates(DatabaseConfig.TODO_TABLE.tableName)
predicates.contains('content', content)
if (content) predicates.contains('content', content)
else {
predicates.glob('content', '*')
}
return await this.todoTable.query(predicates, (_, resSet: relationalStore.ResultSet): TodoData => { return await this.todoTable.query(predicates, (_, resSet: relationalStore.ResultSet): TodoData => {
return { return {

View File

@ -19,7 +19,7 @@ export default class EntryAbility extends UIAbility {
// Main window is created, set main page for this ability // Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/Index', (err, data) => { windowStage.loadContent('pages/TodoPage', (err, data) => {
if (err.code) { if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return; return;

View File

@ -1,19 +1,161 @@
/** /**
* Database apply demo * Database apply demo
*/ */
import TodoTable from '../common/database/tables/TodoTable';
import { TodoData } from '../common/types/Todo';
import { Logger } from '../utils/Logger';
@Preview
@Entry @Entry
@Component @Component
struct Todo { struct TodoPage {
@State message: string = "This a Template Project" @State searchText: string = ''
@State isInput: boolean = false
@State isEdit: boolean = false
@State todoList: TodoData[] = []
private todoTable = new TodoTable()
searchController: SearchController = new SearchController();
addDialogController: CustomDialogController = new CustomDialogController({
builder: AddTodoDialog({ submit: (value) => this.handleAddSubmit(value) }),
cancel: () => this.isInput = false,
})
aboutToAppear() {
this.todoTable.getRdbStore(async () => {
const res = await this.todoTable.query();
this.todoList = res;
})
}
handleSearchSubmit(value: string) {
this.isInput = false
}
async handleAddSubmit(value: string) {
this.isInput = false;
const data = {
id: 0,
content: value,
status: 0,
}
const rowId = await this.todoTable.insertData(data);
data.id = rowId;
this.todoList.push(data)
}
build() { build() {
Row() { Stack() {
Text(this.message) Column() {
.fontSize(40) Row() {
.fontWeight(FontWeight.Bold) Text('Todo List')
.fontWeight(FontWeight.Bold)
.fontSize(24)
Image($rawfile('ic_public_edit.svg'))
.width(24)
.height(24)
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
.alignItems(VerticalAlign.Center)
.margin({ top: 12, bottom: 12 })
Row() {
Search({ value: this.searchText, placeholder: 'Search', controller: this.searchController })
.onChange(value => this.searchText = value)
.onSubmit(this.handleSearchSubmit)
}
.width('100%')
Column() {
ForEach(this.todoList, (item: TodoData) => {
TodoItem({ content: item.content })
})
}
.margin({ top: 12 })
.width('100%')
.alignItems(HorizontalAlign.Start)
}
.padding({ left: 12, right: 12 })
if (!this.isEdit && !this.isInput) {
Button() {
Image($rawfile('add.png'))
}
.width(48)
.height(48)
.markAnchor({ x: '50%', y: '50%' })
.position({ x: '90%', y: '95%' })
.onClick(() => {
// this.isInput = true;
this.addDialogController.open()
})
}
if (this.isEdit) {
Button() {
Image($rawfile('delete.png'))
}
.width(48)
.height(48)
.markAnchor({ x: '50%', y: '50%' })
.position({ x: '90%', y: '95%' })
}
} }
.height('100%') .height('100%')
.width('100%') .width('100%')
.justifyContent(FlexAlign.Center) .alignContent(Alignment.Top)
} }
} }
@CustomDialog
struct AddTodoDialog {
submit: (value) => void = () => {
}
@State inputValue: string = ''
controller: CustomDialogController = new CustomDialogController({
builder: AddTodoDialog({
submit: this.submit,
}),
})
build() {
Column() {
Stack() {
TextInput({ placeholder: "please input" })
.onChange(value => this.inputValue = value)
Button("Submit")
.type(ButtonType.Normal)
.markAnchor({ x: "100%" })
.position({ x: '100%' })
.onClick(() => {
this.submit(this.inputValue);
this.controller.close();
})
}
}
}
}
@Preview
@Component
struct TodoItem {
@Prop content: string = 'Todo'
@Prop showSelect: boolean = false
build() {
Row() {
Text(this.content)
.padding({ left: 8, right: 8 })
if (this.showSelect) {
Checkbox()
}
}
.justifyContent(FlexAlign.SpaceBetween)
.width('100%')
.height(30)
}
}

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Public/ic_public_edit</title>
<defs>
<path d="M16.8722296,2 C17.8721999,2 18.5147251,2.05839169 19.0012003,2.17117304 L17.6599443,3.51379911 C17.4862664,3.50652642 17.2928183,3.5022817 17.0753381,3.50070655 L7.02453833,3.50017541 L6.82305804,3.501658 C5.6550816,3.5151767 5.20981608,3.61305534 4.75370688,3.8569852 C4.36325774,4.06579969 4.06579969,4.36325774 3.8569852,4.75370688 C3.59290159,5.24750032 3.5,5.72858421 3.5,7.1277704 L3.50017541,16.9754617 L3.501658,17.176942 C3.5151767,18.3449184 3.61305534,18.7901839 3.8569852,19.2462931 C4.06579969,19.6367423 4.36325774,19.9342003 4.75370688,20.1430148 C5.22281064,20.3938942 5.68044405,20.4902819 6.92466189,20.4992935 L16.8722296,20.5 C18.2714158,20.5 18.7524997,20.4070984 19.2462931,20.1430148 C19.6367423,19.9342003 19.9342003,19.6367423 20.1430148,19.2462931 C20.3938942,18.7771894 20.4902819,18.319556 20.4992935,17.0753381 L20.5,16.8722296 L20.5,7.1277704 C20.5,6.82616011 20.4956832,6.56721095 20.4862654,6.34159954 L21.8289375,4.9992768 C21.9416465,5.48569497 22,6.12812696 22,7.1277704 L22,16.8722296 L21.9989932,17.0937657 C21.9842401,18.674381 21.8076257,19.3015622 21.487765,19.91208 L21.4657346,19.9536914 C21.1337211,20.5745027 20.6538954,21.0680807 20.0458564,21.4148264 L19.9536914,21.4657346 C19.3018396,21.8143488 18.6552671,22 16.8722296,22 L7.1277704,22 L6.90623426,21.9989932 C5.32561899,21.9842401 4.69843783,21.8076257 4.08791999,21.487765 L4.04630859,21.4657346 C3.42549731,21.1337211 2.93191931,20.6538954 2.58517358,20.0458564 L2.53426541,19.9536914 C2.18565122,19.3018396 2,18.6552671 2,16.8722296 L2,7.1277704 C2,5.38266989 2.17783521,4.72618864 2.51223497,4.08791999 L2.53426541,4.04630859 C2.86627892,3.42549731 3.34610464,2.93191931 3.9541436,2.58517358 L4.04630859,2.53426541 C4.69816044,2.18565122 5.34473292,2 7.1277704,2 L16.8722296,2 Z M22.2300776,1.76992245 C22.6206018,2.16044674 22.6206018,2.79361172 22.2300776,3.18413601 L12.684136,12.7300776 C12.2936117,13.1206018 11.6604467,13.1206018 11.2699224,12.7300776 C10.8793982,12.3395533 10.8793982,11.7063883 11.2699224,11.315864 L20.815864,1.76992245 C21.2063883,1.37939815 21.8395533,1.37939815 22.2300776,1.76992245 Z" id="path-1"></path>
</defs>
<g id="Public/ic_public_edit" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<use id="形状结合" fill="#182431" fill-rule="nonzero" xlink:href="#path-1"></use>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Public/ic_public_input_search</title>
<defs>
<path d="M13.2129889,12.2463949 L15.6099466,14.6430364 C15.9028398,14.9359296 15.9028398,15.4108033 15.6099466,15.7036966 C15.3170533,15.9965898 14.8421796,15.9965898 14.5492864,15.7036966 L12.1424668,13.2968868 C12.5355197,12.9856781 12.8945263,12.6333482 13.2129889,12.2463949 Z M7.78125,1.5 C11.2502886,1.5 14.0625,4.31221142 14.0625,7.78125 C14.0625,9.23090694 13.571411,10.5658639 12.7465202,11.6288338 L12.5852288,11.8281795 C12.5065389,11.9214937 12.4251798,12.0124834 12.3412691,12.1010309 L12.2391385,12.2063305 L12.2391385,12.2063305 L12.1042686,12.3381988 L12.1042686,12.3381988 L12.0040285,12.4312816 L12.0040285,12.4312816 L11.7500714,12.6500283 L11.7500714,12.6500283 L11.6103411,12.7608162 L11.6103411,12.7608162 C10.5503999,13.5770819 9.22251268,14.0625 7.78125,14.0625 C4.31221142,14.0625 1.5,11.2502886 1.5,7.78125 C1.5,4.31221142 4.31221142,1.5 7.78125,1.5 Z M7.78125,3 C5.14063854,3 3,5.14063854 3,7.78125 C3,10.4218615 5.14063854,12.5625 7.78125,12.5625 C10.4218615,12.5625 12.5625,10.4218615 12.5625,7.78125 C12.5625,5.14063854 10.4218615,3 7.78125,3 Z" id="path-1"></path>
</defs>
<g id="Public/ic_public_input_search" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="形状" fill-rule="nonzero"></g>
<g id="编组" mask="url(#mask-2)" fill="#000000" fill-opacity="0.9">
<g id="Symbol/color-light/colorPrimary">
<rect id="color/#000000" x="0" y="0" width="18" height="18"></rect>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -1,13 +1,12 @@
{ {
"name": "myapplication",
"version": "1.0.0",
"description": "Please describe the basic information.",
"main": "",
"author": "",
"license": "", "license": "",
"dependencies": {
},
"devDependencies": { "devDependencies": {
"@ohos/hypium": "1.0.6" "@ohos/hypium": "1.0.6"
}, },
"author": "",
"name": "myapplication",
"description": "Please describe the basic information.",
"main": "",
"version": "1.0.0",
"dependencies": {}
} }