我做了什么
我在 donejs 中创建了一个组件,然后创建了两个超模contact
并email
使用以下命令:
donejs add component contactComponent contact-component
donejs add supermodel contact
donejs add supermodel email
有一个提供联系人和电子邮件的 API (feathers+mongodb)。每封电子邮件都有一个contactId
.
该组件包含Contact
模型并处理诸如保存、创建新元素、删除元素等操作。将其与.stache
文件组合时,它将成功地从 API 中检索元素并相应地列出它们。
所以每个Contact
人都有电子邮件。由于每个联系人都有自己的电子邮件,因此contactComponent 无法直接获取它们,而是通过 Contact
元素获取它们。
这就是我的设计问题开始的地方。
到目前为止,contactComonent 创建了一个处理联系人处理方式的视图模型。联系人模型处理 API 连接。这工作正常,可扩展且干净。
但是每个联系人都需要一个新模型来加载数据(电子邮件),然后我直接使用该模型来管理与电子邮件相关的所有逻辑。这确实有效,但似乎让模型处理连接和处理复杂交互的视图模型更适合 MVVM 设计模式。
我想我不是第一个进行此类数据建模的人,我认为必须有更好的解决方案,尤其是在处理大量关系和更复杂的关系时。
我认为我目前拥有的是这样的:
contactComponent.js
├── (includes) models/contact.js
│ ├── (includes) models/email.js
这就是我正在寻找的(我可能错了)
contactComponent.js
├── (includes) models/contact.js
├── (includes / relates / references) emailComponent.js
emailComponent.js
├── (includes) models/email.js
使用过的文件
文件结构contactComponent
├── contactComponent.js
├── contactComponent.stache
models
├── contact.js
├── email.js
联系人组件/contactComponent.js
/* contactComponent/contactComponent.js */
import Component from 'can/component/';
import Map from 'can/map/';
import 'can/map/define/';
import template from './contactComponet.stache!';
import Contact from '../models/contact.js';
export const ViewModel = Map.extend({
define: {
contactPromise: {
get: function() {
return Contact.getList({});
}
}
},
saveContact: function() {
// do some stuff
},
deleteContact: function() {
// do some stuff
}
});
export default Component.extend({
tag: 'contact-component',
viewModel: ViewModel,
template
});
contactComponent/contactComponent.stache
/* contactComponent/contactComponent.stache */
{{#if contactPromise.isResolved}}
{{#each contactPromise.value}}
Name: {{name}}
{{#if emailPromise.isResolved}}
Emails:
{{#each emailPromise.value}}
{{email}}
{{/each}}
{{/if}}
{{/each}}
{{/if}}
模型/email.js
/* models/email.js */
import can from 'can';
import superMap from 'can-connect/can/super-map/';
import tag from 'can-connect/can/tag/';
import 'can/map/define/define';
export const Email = can.Map.extend({
define: {},
type: null,
email: null,
});
Email.List = can.List.extend({
Map: Email
}, {});
export const emailConnection = superMap({
url: '/api/modelEmail',
idProp: '_id',
Map: Email,
List: Email.List,
name: 'email'
});
tag('email-model', emailConnection);
export default Email;
这是事情开始变得过于复杂的地方:
模型/contact.js/* models/contact.js */
import can from 'can';
import superMap from 'can-connect/can/super-map/';
import tag from 'can-connect/can/tag/';
import 'can/map/define/define';
import Email from '../models/email.js';
export const Contact = can.Map.extend({
define: {
emailPromise: {
get: function() {
return Email.getList({ contactId: this.attr('id') });
}
}
},
name: null,
});
Contact.List = can.List.extend({
Map: Contact
}, {});
export const contactConnection = superMap({
url: '/api/modelContact',
idProp: '_id',
Map: Contact,
List: Contact.List,
name: 'contact'
});
tag('contact-model', contactConnection);
export default Contact;