# Model
# Create model class
Simply usage
export class TaskModel extends Model {
// you code here
}
Advanced
import { Model } from '@zidadindimon/vue-mc';
export type Timestamp = number;
export enum TASK_STATUS {
NEW = 'new',
PROCESSING = 'processing',
PAUSE = 'pause',
DONE = 'done',
}
export interface Task {
readonly id: number;
title: string;
description: string;
assignTo: string;
status: TASK_STATUS;
createdAt: Date;
updatedAt: Date;
}
/**
* here we extends class Model and
*/
export class TaskModel extends Model implements Task {
//...
}
# Initialize
// TaskModel.ts
export class TaskModel extends Model<Task> implements Task {
//...
}
In vue component
@Component({})
export default class SomeComponentForm extends Vue {
model: TaskModel = new TaskModel()
@Prop(Number) id: number;
@Watch('id')
async fetch(): Promise<void> {
await this.model.fetch({ id: this.id });
}
}
or
@Component({})
export default class PostListItem extends Vue {
@Prop(PostModel) readonly model: PostModel;
}
or
const data: Task = {
id: 1,
title: 'Title',
// ...
}
const model = new TaskModel().init(data, false);
# Default value
In order to specify a default value, it is enough to specify the attributes of the model and set them values.
export class TaskModel extends Model implements Task {
readonly id: number = null;
description: string = null;
status: TASK_STATUS = TASK_STATUS.NEW;
title: string = null;
assignTo: string = null;
// apply default value
createdAt: Date = new Date();
updatedAt: Date = new Date();
//...
}
Always specify a default value or null for attributes to be reactive; ⚠️ ⚠️ ⚠️
# Mutations
When you want to bring the input (types) to the model data (types), you can use the mutations' method as shown in the example below
export class TaskModel extends Model<TaskDto> implements Task {
// call wehen initialize model
protected mutations(data: TaskDto): MutationList<Task> {
return {
createdAt: () => new Date(data.createdAt),
author: () => data.author ? `${data.author.firstName} ${data.author.lastName}` : ''
};
}
// call before save/update model (RESTapi)
protected mutateBeforeSave(): MutationList<TaskDto> {
return {
...this,
createdAt: this.createdAt.valueOf(),
updatedAt: this.updatedAt.valueOf(),
};
}
}
# Computed value
export class TaskModel extends Model<TaskDto> implements Task {
get dateFormat(): string {
return this.createdAt.toDateString();
}
}
# GRUD operation
Api of Model provide next api operation:
fetch
- initialize model from some sourcesave
- create new record on some source or update existingdelete
- delete record in some source
Configure api provider:
// sample api.provider.ts
import { ModelApiProvider } from '@zidadindimon/vue-mc';
export const apiProvider: ModelApiProvider<TaskDto, TaskDto, ModelFetchDto, ModelFetchDto> = {
async fetch(data?: ModelFetchDto): Promise<TaskDto> {
// use axios or fetc for http reguest
},
async save(data?: TaskDto): Promise<TaskDto> {
// use axios or fetc for http reguest
},
async update(data?: TaskDto): Promise<TaskDto> {
// use axios or fetc for http reguest
},
delete(data?: ModelFetchDto): Promise<any> {
// use axios or fetc for http reguest
}
};
add api provider to model
export class TaskModel extends Model<TaskDto, TaskDto, ModelFetchDto, ModelFetchDto> implements Task {
//...
protected api(): ModelApiProvider<TaskDto, TaskDto, ModelFetchDto, ModelFetchDto> {
return apiProvider;
}
//...
}
Usage:
@Component({})
export default class TodoForm extends Vue {
model: TaskModel = new TaskModel()
@Prop(Number) id: number;
@Watch('id')
async fetch(): Promise<void> {
await this.model.fetch({ id: this.id });
}
get formErrors() {
return this.model.errors.attrs || {};
}
async save(): Promise<void> {
try {
await this.model.save();
} catch (e) {
// do something with errors
console.error(e);
}
}
}
# Hooks
Also, you can use and override next hooks
beforeSave
- run before callsave
methodonSave
- run after callsave
methodbeforeFetch
- run before callfetch
methodonFetch
- run after callfetch
methodbeforeDelete
- run before calldelete
methodonError
- run after any api method if
# Processing indicators
You can also use the following indicators when requesting a server:
loading
saving
deleting
# Validation
Sometimes you need to validate the data before sending it to the server. This is done very simply. Just describe the validation rules in the model:
export class TaskModel extends Model<TaskDto, TaskDto, ModelFetchDto, ModelFetchDto> implements Task {
rules(): RuleList<Task> {
return {
title: [
(v) => !!v || 'Title can`t be empty',
],
description: [
(v) => !!v || 'Description can`t be empty',
(v) => v.length > 15 || 'Description must be more 15 symbols',
],
assignTo: [
(v) => !!v || 'Assign to can`t be empty',
],
};
}
}
If call save method and validation failed than method throw ValidateException
;
Get validation error:
this.model.errors.attrs
Other model error
this.model.errors.model
if you want to disable validation before save or update use next:
this.model.validationBeforeSave = false