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

在这里插入图片描述

📌 概述

收藏旅行页面用于展示用户标记为收藏的旅行记录。收藏功能是一个常见的用户交互,允许用户快速访问他们最喜欢或最重要的旅行记录。在 Cordova 与 OpenHarmony 的混合开发框架中,收藏功能需要涉及数据库操作、UI 状态管理、以及原生层的性能优化。本文将详细讲解如何实现一个完整的收藏管理系统。

🔗 完整流程

第一步:收藏状态管理与数据库操作

收藏功能需要在数据库中维护一个收藏状态标志。当用户点击收藏按钮时,需要更新数据库中对应旅行记录的收藏状态。收藏状态的变化需要实时反映在 UI 上,提供良好的用户反馈。

数据库操作包括:查询所有收藏的旅行、更新旅行的收藏状态、删除收藏等。这些操作需要通过异步方式进行,避免阻塞 UI。

第二步:收藏列表渲染与交互

收藏页面需要展示所有被收藏的旅行记录。与全部旅行页面类似,收藏页面也需要实现分页加载、搜索筛选等功能。用户可以在收藏页面中取消收藏,也可以查看旅行详情。

收藏列表的渲染需要考虑空状态处理,当没有收藏的旅行时,应该显示友好的提示信息。

第三步:原生层收藏同步与通知

OpenHarmony 原生层可以实现收藏状态的同步和通知。当用户在不同页面进行收藏操作时,原生层可以确保所有页面的收藏状态保持一致。原生层还可以实现收藏变化的通知机制,实时更新 UI。

🔧 Web 代码实现

收藏页面 HTML 结构

<div id="favorites-page" class="page">
    <div class="page-header">
        <h1>收藏旅行</h1>
        <span class="header-count" id="favoriteCount">0</span>
    </div>
    
    <div class="favorites-container">
        <div class="favorites-list" id="favoritesList">
            <!-- 收藏列表动态加载 -->
        </div>
        <div class="empty-state" id="emptyState" style="display: none;">
            <div class="empty-icon"></div>
            <p>还没有收藏任何旅行</p>
            <button class="btn btn-primary" onclick="navigateTo('all-trips')">
                去收藏旅行
            </button>
        </div>
    </div>
</div>

HTML 结构包含收藏列表容器和空状态提示。当没有收藏的旅行时,显示空状态提示,引导用户去收藏旅行。

加载收藏列表函数

async function loadFavorites() {
    try {
        // 从数据库查询所有旅行
        const allTrips = await db.getAllTrips();
        
        // 筛选出收藏的旅行
        const favorites = allTrips.filter(trip => trip.isFavorite === true);
        
        // 更新收藏计数
        document.getElementById('favoriteCount').textContent = favorites.length;
        
        // 处理空状态
        if (favorites.length === 0) {
            document.getElementById('emptyState').style.display = 'block';
            document.getElementById('favoritesList').innerHTML = '';
            return;
        }
        
        document.getElementById('emptyState').style.display = 'none';
        
        // 渲染收藏列表
        renderFavoritesList(favorites);
        
        // 通知原生层更新收藏状态
        if (window.cordova) {
            cordova.exec(
                (result) => console.log('Favorites updated:', result),
                (error) => console.error('Update error:', error),
                'FavoritesPlugin',
                'onFavoritesUpdated',
                [{ count: favorites.length, timestamp: Date.now() }]
            );
        }
    } catch (error) {
        console.error('Error loading favorites:', error);
        showToast('加载收藏列表失败');
    }
}

这个函数从数据库查询所有旅行,然后筛选出 isFavorite 为 true 的记录。函数还处理了空状态,当没有收藏时显示提示信息。最后通知原生层更新收藏状态。

收藏列表渲染函数

function renderFavoritesList(favorites) {
    const container = document.getElementById('favoritesList');
    container.innerHTML = '';
    
    favorites.forEach(trip => {
        const favoriteElement = document.createElement('div');
        favoriteElement.className = 'favorite-item';
        favoriteElement.id = `favorite-${trip.id}`;
        favoriteElement.innerHTML = `
            <div class="favorite-header">
                <h3>${trip.destination}</h3>
                <button class="btn-favorite" onclick="toggleFavorite(${trip.id}, false)" 
                        title="取消收藏">⭐</button>
            </div>
            <div class="favorite-body">
                <p class="trip-description">${trip.description || '暂无描述'}</p>
                <div class="trip-meta">
                    <span>📅 ${formatDate(trip.startDate)}</span>
                    <span>💰 ¥${trip.expense}</span>
                </div>
            </div>
            <div class="favorite-footer">
                <button class="btn-small" onclick="navigateTo('trip-detail', ${trip.id})">
                    查看详情
                </button>
                <button class="btn-small" onclick="editTrip(${trip.id})">
                    编辑
                </button>
            </div>
        `;
        container.appendChild(favoriteElement);
    });
}

收藏列表渲染函数为每个收藏的旅行创建一个 DOM 元素。收藏按钮使用星形图标,点击可以取消收藏。每个收藏项都包含旅行的基本信息和操作按钮。

切换收藏状态函数

async function toggleFavorite(tripId, isFavorite) {
    try {
        // 更新数据库
        const trip = await db.getTrip(tripId);
        trip.isFavorite = isFavorite;
        await db.updateTrip(trip);
        
        // 更新 UI
        if (isFavorite) {
            showToast('已收藏');
        } else {
            showToast('已取消收藏');
            // 从收藏页面移除该项
            const element = document.getElementById(`favorite-${tripId}`);
            if (element) {
                element.remove();
            }
            // 重新加载收藏列表
            loadFavorites();
        }
        
        // 通知原生层
        if (window.cordova) {
            cordova.exec(
                (result) => console.log('Favorite toggled:', result),
                (error) => console.error('Toggle error:', error),
                'FavoritesPlugin',
                'onFavoriteToggled',
                [{ tripId: tripId, isFavorite: isFavorite }]
            );
        }
    } catch (error) {
        console.error('Error toggling favorite:', error);
        showToast('操作失败,请重试');
    }
}

切换收藏状态函数更新数据库中的收藏标志,然后更新 UI。如果取消收藏,直接从页面移除该项。函数还通知原生层收藏状态的变化。

🔌 OpenHarmony 原生代码实现

收藏状态同步插件

// FavoritesPlugin.ets
import { BusinessError } from '@ohos.base';

export class FavoritesPlugin {
    private favoritesObservers: Function[] = [];
    
    // 处理收藏更新事件
    onFavoritesUpdated(args: any, callback: Function): void {
        try {
            const count = args[0].count;
            const timestamp = args[0].timestamp;
            
            // 记录收藏状态变化
            console.log(`[Favorites] Count: ${count}, Timestamp: ${timestamp}`);
            
            // 通知所有观察者
            this.notifyObservers({
                type: 'favoritesUpdated',
                count: count,
                timestamp: timestamp
            });
            
            callback({ success: true, message: '收藏状态已同步' });
        } catch (error) {
            callback({ success: false, error: error.message });
        }
    }
    
    // 处理收藏切换事件
    onFavoriteToggled(args: any, callback: Function): void {
        try {
            const tripId = args[0].tripId;
            const isFavorite = args[0].isFavorite;
            
            // 更新本地状态
            this.updateLocalFavoriteState(tripId, isFavorite);
            
            // 通知观察者
            this.notifyObservers({
                type: 'favoriteToggled',
                tripId: tripId,
                isFavorite: isFavorite
            });
            
            callback({ success: true, message: '收藏状态已更新' });
        } catch (error) {
            callback({ success: false, error: error.message });
        }
    }
    
    // 更新本地收藏状态
    private updateLocalFavoriteState(tripId: number, isFavorite: boolean): void {
        // 这里可以实现本地缓存的更新逻辑
        console.log(`[Favorites] Trip ${tripId} favorite state: ${isFavorite}`);
    }
    
    // 通知所有观察者
    private notifyObservers(event: any): void {
        this.favoritesObservers.forEach(observer => {
            try {
                observer(event);
            } catch (error) {
                console.error('[Favorites] Observer error:', error);
            }
        });
    }
    
    // 注册观察者
    registerObserver(observer: Function): void {
        this.favoritesObservers.push(observer);
    }
}

收藏状态同步插件实现了观察者模式,允许多个组件订阅收藏状态的变化。当收藏状态改变时,插件会通知所有观察者,确保应用中所有相关的 UI 都能及时更新。

收藏通知机制

// FavoriteNotificationPlugin.ets
export class FavoriteNotificationPlugin {
    // 发送收藏通知
    sendFavoriteNotification(args: any, callback: Function): void {
        try {
            const tripName = args[0].tripName;
            const action = args[0].action; // 'added' 或 'removed'
            
            let message = '';
            if (action === 'added') {
                message = `已收藏 "${tripName}"`;
            } else {
                message = `已取消收藏 "${tripName}"`;
            }
            
            console.log(`[Notification] ${message}`);
            
            callback({
                success: true,
                message: message,
                timestamp: Date.now()
            });
        } catch (error) {
            callback({ success: false, error: error.message });
        }
    }
}

通知插件负责向用户发送收藏操作的反馈。通过清晰的消息提示,用户可以确认他们的操作是否成功。

⭐ 收藏功能的设计模式

收藏功能是一个常见的用户交互,但实现一个完整的收藏系统需要考虑很多细节。首先是收藏状态的管理。收藏状态需要在多个页面之间同步,当用户在一个页面收藏旅行时,其他页面应该立即反映这个变化。这可以通过观察者模式实现,当收藏状态改变时,通知所有观察者进行更新。

其次是收藏的持久化。收藏状态需要保存到数据库中,确保用户关闭应用后再打开时,收藏状态仍然保留。如果应用支持云同步,收藏状态也需要同步到云端,确保用户在不同设备上看到一致的收藏列表。

第三是收藏的性能。当用户有大量收藏时,加载收藏列表可能会很慢。需要使用分页加载、缓存等技术来优化性能。

🔔 用户反馈与通知

收藏操作需要提供清晰的用户反馈。当用户点击收藏按钮时,应该立即显示视觉反馈,如按钮颜色改变、图标变化等。同时应该显示一个短暂的提示信息,如"已收藏"或"已取消收藏"。

对于重要的收藏操作,可以发送通知。例如,当用户收藏一个旅行时,可以发送一个通知提醒用户。这样可以增强用户的参与感。

📊 收藏统计与分析

收藏功能可以提供一些有趣的统计数据。例如,可以统计用户最常收藏的目的地、最常收藏的时间段等。这些统计数据可以帮助用户了解自己的旅行偏好。

收藏数据也可以用于推荐。如果用户经常收藏某个目的地的旅行,应用可以推荐相关的旅行。这样可以提高用户的参与度。

🎯 收藏列表的排序与分组

收藏列表可以按不同的方式排序。默认可以按收藏时间排序,最近收藏的显示在最前面。也可以按目的地、日期、花费等排序,让用户快速找到想要的旅行。

收藏列表也可以按不同的维度分组。例如,按目的地分组,让用户看到每个目的地有多少个收藏。按时间分组,让用户看到不同时期的收藏。这样可以提供更多的信息维度。

🔐 收藏的隐私与共享

如果应用支持分享功能,用户可能想要分享他们的收藏。但是收藏列表可能包含私人信息,需要提供隐私控制。用户应该能够选择哪些收藏是公开的,哪些是私人的。

分享收藏时,应该只分享公开的收藏。接收分享的用户可以查看分享的收藏,也可以选择收藏这些旅行。这样可以实现社交功能,增强应用的互动性。

💡 收藏与其他功能的集成

收藏功能应该与应用的其他功能紧密集成。例如,在旅行详情页面,应该显示收藏按钮。在搜索结果中,应该显示哪些旅行已被收藏。在推荐页面,应该根据用户的收藏推荐相关的旅行。

收藏功能也可以与筛选功能集成。用户可以筛选出所有收藏的旅行,或者筛选出未收藏的旅行。这样可以提供更灵活的查询能力。

📝 总结

收藏旅行页面展示了如何在 Cordova 与 OpenHarmony 框架中实现一个完整的收藏管理系统。Web 层负责 UI 渲染和用户交互,原生层负责状态同步和通知管理。通过观察者模式和事件通知机制,实现了跨页面的状态同步,提供了良好的用户体验。在实现过程中,需要重点关注状态同步、用户反馈、性能优化等方面,确保收藏功能能够提供最佳的用户体验。

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐