在WatermelonDB模型类外调用@writer方法失败求助
问题原因与解决方案
你的核心问题是对WatermelonDB的模型与集合的方法归属理解错误:你在Post模型类里定义的createPost和updatePost是模型实例方法(属于单个Post对象),但你在组件里试图从postCollection(集合对象)上去调用这些方法,自然找不到。
另外原模型代码的逻辑也不合理:创建新Post的方法不该写在模型实例里(因为创建时还没有实例),更新方法也不该在一个实例里去查找另一个实例。
方案一:直接使用WatermelonDB原生API(推荐)
不需要自定义模型方法,直接用集合的原生create和模型实例的update方法,它们本身就支持事务处理:
修改组件代码
export const Style = () => { const database = useDatabase(); const postCollection = database.collections.get<Post>('posts'); // 创建Post const createPost = async (newPost: PostType) => { try { await postCollection.create(post => { post.postId = newPost.postId; post.rowModifiedAt = newPost.rowModifiedAt; post.title = newPost.title; post.body = newPost.body; }); console.log('Post created successfully'); } catch (error) { console.error('Error creating post:', error); } }; // 更新Post const updatePost = async (postData: PostType) => { try { // 先找到要更新的Post实例 const targetPost = await postCollection.find(String(postData.postId)); await targetPost.update(post => { // 注意:postId作为主键不建议修改 post.rowModifiedAt = postData.rowModifiedAt; post.title = postData.title; post.body = postData.body; }); console.log('Post updated successfully'); } catch (error) { console.error('Error updating post:', error); } }; // ... 其他组件逻辑 };
方案二:封装方法到集合类(如果需要自定义封装)
如果你希望把创建/更新逻辑封装成集合的方法,可以扩展Collection类:
1. 创建自定义集合类
// post-collection.ts import { Collection } from '@nozbe/watermelondb'; import { writer } from '@nozbe/watermelondb/decorators'; import Post from './Post'; import PostType from '@/data/types/post'; export class PostCollection extends Collection<Post> { @writer async createPost(postData: PostType) { return await this.create(post => { post.postId = postData.postId; post.rowModifiedAt = postData.rowModifiedAt; post.title = postData.title; post.body = postData.body; }); } @writer async updatePost(postData: PostType) { const targetPost = await this.find(String(postData.postId)); await targetPost.update(post => { post.rowModifiedAt = postData.rowModifiedAt; post.title = postData.title; post.body = postData.body; }); } }
2. 数据库初始化时绑定自定义集合
// database.ts import { Database } from '@nozbe/watermelondb'; import SQLiteAdapter from '@nozbe/watermelondb/adapters/sqlite'; import schema from './schema'; import Post from './models/Post'; import { PostCollection } from './models/post-collection'; const adapter = new SQLiteAdapter({ schema }); const database = new Database({ adapter, modelClasses: [Post], // 绑定自定义集合类 collectionClasses: { posts: PostCollection, }, }); export default database;
3. 组件中调用自定义方法
export const Style = () => { const database = useDatabase(); // 断言类型为自定义的PostCollection const postCollection = database.collections.get<Post>('posts') as PostCollection; const createPost = async (newPost: PostType) => { try { await postCollection.createPost(newPost); console.log('Post created successfully'); } catch (error) { console.error('Error creating post:', error); } }; // ... 其他组件逻辑 };
内容的提问来源于stack exchange,提问作者Smeagol
相关产品推荐
相关产品推荐

