在这里插入图片描述

欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。

本文对应模块:Web 层的标签系统实现,包括标签的创建管理、任务标记、标签查询统计,以及与原生层的标签同步机制。

📌 概述

标签系统提供了一种灵活的任务分类方式,与分类不同的是,一个任务可以拥有多个标签,这样可以从多个维度对任务进行分类和组织。标签系统包括标签的创建、删除、查询和统计功能。TagManager 类是标签管理的核心,负责管理所有标签和任务标签的关联关系。通过标签系统,用户可以更加灵活地组织和查找任务。

🔗 标签系统的完整流程

标签系统分为三层:Web 层的 TagManager(标签管理器)负责业务逻辑,DatabaseModule(数据库模块)负责数据的持久化和查询,IndexedDB 是底层的本地数据库。当用户创建标签时,TagManager 接收标签名称,首先检查标签是否已存在,如果不存在则调用 DatabaseModule 的 addTag 方法将标签保存到 IndexedDB。当用户为任务添加标签时,需要更新任务的标签列表。当用户查询标签时,TagManager 调用 DatabaseModule 的查询方法从 IndexedDB 获取数据。TagManager 还提供了标签的统计功能,可以计算每个标签下的任务数量和完成情况。

标签系统与分类系统的主要区别在于,分类是一对一的关系,每个任务只能属于一个分类,而标签是多对多的关系,一个任务可以有多个标签,一个标签也可以被多个任务使用。这种灵活的关联方式使得用户可以从多个维度对任务进行组织和查询。例如,一个任务可以同时拥有"紧急"、“工作”、"高优先级"等多个标签,这样用户可以通过任何一个标签来查找相关的任务。

标签系统的实现需要考虑以下几个方面:首先是标签的创建和管理,需要防止重复创建相同的标签。其次是任务与标签的关联,需要维护任务和标签之间的多对多关系。第三是标签的查询和统计,需要快速查找具有某个标签的所有任务,以及统计每个标签下的任务数量。最后是标签的删除,需要考虑删除标签时是否删除与该标签关联的任务,通常的做法是只删除标签本身,保留任务。

🔧 标签管理器实现

标签管理器的核心实现包括标签的增删查、任务标签关联、统计和查询功能。标签创建时需要验证标签名称不能为空,并检查标签是否已存在,避免重复创建。标签删除时只删除标签本身,不删除与该标签关联的任务。标签统计时计算每个标签下的任务总数和已完成数。

// 标签管理器的关键方法
class TagManager {
    constructor() {
        this.tags = [];
    }

    async init() {
        await this.loadTags();
    }

    async createTag(tagName) {
        if (!tagName?.trim()) throw new Error('标签名称不能为空');
        const existing = this.tags.find(t => t.name === tagName);
        if (existing) return existing.id;
        
        const id = await db.addTag({ name: tagName });
        await this.loadTags();
        return id;
    }

    async deleteTag(id) {
        await db.deleteTag(id);
        await this.loadTags();
    }

    getTagsByTask(taskId) {
        const task = taskManager.getTask(taskId);
        return task?.tags || [];
    }

    getTasksByTag(tagName) {
        return taskManager.getAllTasks().filter(t =>
            t.tags && t.tags.includes(tagName)
        );
    }

    getTagStats() {
        const stats = {};
        this.tags.forEach(tag => {
            const tasks = this.getTasksByTag(tag.name);
            stats[tag.name] = {
                total: tasks.length,
                completed: tasks.filter(t => t.status === 'completed').length
            };
        });
        return stats;
    }
}

const tagManager = new TagManager();

代码解释:

TagManager 类提供了一个完整的标签管理接口。init() 方法在初始化时加载所有标签。createTag() 方法创建新标签,首先验证标签名称不能为空,然后检查标签是否已存在,如果存在则直接返回该标签的 ID,避免重复创建。如果标签不存在,则调用数据库的 addTag() 方法保存标签。deleteTag() 方法删除标签,只删除标签本身,不影响与该标签关联的任务。getTagsByTask() 方法获取指定任务的所有标签。getTasksByTag() 方法获取具有指定标签的所有任务,通过过滤任务的标签列表实现。getTagStats() 方法计算每个标签下的任务统计信息,包括总数和已完成数,这对于显示标签的使用情况非常有用。

🔌 原生层的标签系统同步

HarmonyOS 原生层也需要与 Web 层的标签系统进行集成。原生层可以通过 Cordova 插件来接收来自 Web 层的标签变化事件。

// ArkTS 代码示例 - 标签系统插件
import { CordovaPlugin, CallbackContext } from '@magongshou/harmony-cordova/Index';
import { PluginResult, MessageStatus } from '@magongshou/harmony-cordova/Index';

export class TagSyncPlugin extends CordovaPlugin {
    // 监听 Web 层的标签变化
    async onTagChanged(callbackContext: CallbackContext, args: string[]): Promise<void> {
        try {
            const tagData = JSON.parse(args[0]);
            const action = args[1]; // 'created', 'deleted'
            console.log('[TagSyncPlugin] 标签已' + action + ':', tagData.name);
            
            // 原生层可以根据标签变化更新自己的数据
            const result = PluginResult.createByString(MessageStatus.OK, '标签已同步');
            callbackContext.sendPluginResult(result);
        } catch (error) {
            const result = PluginResult.createByString(MessageStatus.ERROR, (error as Error).message);
            callbackContext.sendPluginResult(result);
        }
    }

    // 监听 Web 层的任务标签变化
    async onTaskTagsChanged(callbackContext: CallbackContext, args: string[]): Promise<void> {
        try {
            const taskId = args[0];
            const tags = JSON.parse(args[1]);
            console.log('[TagSyncPlugin] 任务标签已更新:', taskId, tags);
            
            const result = PluginResult.createByString(MessageStatus.OK, '任务标签已同步');
            callbackContext.sendPluginResult(result);
        } catch (error) {
            const result = PluginResult.createByString(MessageStatus.ERROR, (error as Error).message);
            callbackContext.sendPluginResult(result);
        }
    }
}

原生代码解释:

TagSyncPlugin 是一个 Cordova 插件,提供了原生层与 Web 层标签系统的交互接口。onTagChanged 方法监听 Web 层的标签创建和删除事件,接收标签数据和操作类型。onTaskTagsChanged 方法监听 Web 层的任务标签变化事件,接收任务 ID 和标签列表。原生层可以根据这些事件更新自己的数据或执行相应的操作,例如更新原生层的标签列表或任务标签关联。

Web 层通知原生标签变化

Web 层可以调用原生插件来通知原生层标签已变化:

// JavaScript 代码 - 通知原生标签变化
function notifyTagChanged(tagData, action) {
    cordova.exec(
        function() { console.log('原生层已收到标签变化通知'); },
        function(error) { console.error('通知失败:', error); },
        'TagSyncPlugin',
        'onTagChanged',
        [JSON.stringify(tagData), action]
    );
}

// 通知原生任务标签变化
function notifyTaskTagsChanged(taskId, tags) {
    cordova.exec(
        function() { console.log('原生层已收到任务标签变化通知'); },
        function(error) { console.error('通知失败:', error); },
        'TagSyncPlugin',
        'onTaskTagsChanged',
        [taskId, JSON.stringify(tags)]
    );
}

Web 层代码解释:

notifyTagChanged 函数使用 cordova.exec() 调用原生插件的 onTagChanged 方法,传递标签数据和操作类型。notifyTaskTagsChanged 函数调用原生插件的 onTaskTagsChanged 方法,传递任务 ID 和标签列表。这样可以从 Web 层通知原生层标签和任务标签已变化。当用户在 Web 层创建、删除标签或为任务添加、移除标签时,都会通过这些函数通知原生层,保持两层的数据同步。

� 总结

标签系统是应用的重要功能,通过灵活的多对多标签关联,用户可以从多个维度对任务进行组织和查询。通过与原生层的集成,可以实现标签数据的完整同步。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐