You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Every service now includes a new `FeathersVuexModel` Class and new records are instantiated with that class before getting added to the store.
6
+
# Data Modeling with Model Classes
7
+
8
+
Feathers-Vuex 1.0 introduced some lightweight data modeling. Every service had its own, internal `FeathersVuexModel`. In version 2.0 this `FeathersVuexModel` is now called the `BaseModel` and is extendable, so you can add your own functionality.
9
+
10
+
11
+
## Extending the BaseModel Class
12
+
13
+
While [setting up Feathers-Vuex](/api-overview.html#feathers-client-feathers-vuex), we exported the `BaseModel` class so that we could extend it. The below example shows how to import and extend the `BaseModel`. Each service must now have its own unique Model class.
// Required for $FeathersVuex plugin to work after production transpile.
20
+
static modelName ='User'
21
+
// Define default properties here
22
+
staticinstanceDefaults() {
23
+
return {
24
+
email:'',
25
+
password:''
26
+
}
27
+
}
28
+
}
29
+
30
+
constservicePath='users'
31
+
constservicePlugin=makeServicePlugin({
32
+
Model: User,
33
+
service:feathersClient.service(servicePath),
34
+
servicePath
35
+
})
36
+
```
37
+
38
+
In case you're wondering, the `modelName` property is used to get around transpilation errors when using Babel with ES3 or ES5. Babel is still installed by default in most projects and generators. The `modelName` is used instead of the `name` property to provide a reliable name AFTER transpilation.
39
+
40
+
If you're working in an environment that doesn't support static properties on classes, you can always specify the static properties using the dot operator:
41
+
42
+
```js
43
+
classUserextendsBaseModel {}
44
+
45
+
User.modelName='User'
46
+
User.instanceDefaults=function() {
47
+
return {
48
+
email:'',
49
+
password:''
50
+
}
51
+
}
52
+
```
7
53
8
54
## Model attributes
9
55
@@ -15,62 +61,85 @@ The following attributes are available on each model:
15
61
16
62
## Model Methods
17
63
18
-
### Model.find(params)
64
+
### find(params)
19
65
20
66
Model classes have a `find` method, which is a proxy to the [`find` action](./service-plugin.html#find-params). <Badgetext="1.7.0+" />
21
67
22
68
```js
23
69
// In your Vue component
24
70
created () {
25
-
const { Todo } =this.$FeathersVuex
71
+
const { Todo } =this.$FeathersVuex.api
26
72
Todo.find({ query: {} }).then(/* ... */)
27
73
}
28
74
```
29
75
30
-
### Model.findInStore(params)
76
+
### findInStore(params)
31
77
32
78
Model classes have a `findInStore` method, which is a proxy to the [`find` getter](./service-plugin.html#Service-Getters). <Badgetext="1.7.0+" />
33
79
34
80
```js
35
81
// In your Vue component
36
82
created () {
37
-
const { Todo } =this.$FeathersVuex
83
+
const { Todo } =this.$FeathersVuex.api
38
84
consttodos=Todo.findInStore({ query: {} })
39
85
}
40
86
```
41
87
42
-
### Model.get(id, params)
88
+
### get(id, params)
43
89
44
-
Model classes have a `get` method, which is a proxy to the [`get` action](./service-plugin.html#get-id-or-get-id-params). <Badgetext="1.7.0+" />Notice that the signature is more Feathers-like, and doesn't require using an array to passing both id and params.
90
+
Model classes have a `get` method, which is a proxy to the [`get` action](./service-plugin.html#get-id-or-get-id-params). <Badgetext="1.7.0+" />Notice that the signature is more Feathers-like, and doesn't require using an array to passing both id and params.
45
91
46
92
```js
47
93
// In your Vue component
48
94
created () {
49
-
const { Todo } =this.$FeathersVuex
95
+
const { Todo } =this.$FeathersVuex.api
50
96
Todo.get(this.id).then(/* ... */)
51
97
}
52
98
```
53
99
54
-
### Model.getFromStore(id, params)
100
+
### getFromStore(id, params)
55
101
56
102
Model classes have a `getFromStore` method, which is a proxy to the [`get` getter](./service-plugin.html#Service-Getters). <Badgetext="1.7.0+" /> Notice that the signature is more Feathers-like, and doesn't require using an array to passing both id and params.
57
103
58
104
```js
59
105
// In your Vue component
60
106
created () {
61
-
const { Todo } =this.$FeathersVuex
107
+
const { Todo } =this.$FeathersVuex.api
62
108
consttodo=Todo.getFromStore(this.id)
63
109
}
64
110
```
65
111
112
+
### instanceDefaults <Badgetext="1.7.0+" />
113
+
114
+
`instanceDefaults(data, { store, Models })`
115
+
116
+
Starting with version 2.0, `instanceDefaults` must be provided as a function. The function will be called with the following arguments and should return an object of default properties for new instances.
117
+
118
+
-`data {Object}` - The instance data
119
+
- An `utils` object containing these props:
120
+
-`store` - The vuex store
121
+
-`Models {Object}` The `globalModels` object, which is the same as you'll find inside a component at `this.$FeathersVuex`.
122
+
123
+
### setupInstance <Badgetext="2.0.0+" />
124
+
125
+
`setupInstance(data, { store, Models })`
126
+
127
+
A new `setupinstance` class method is now available in version 2.0. The function will be called with the following arguments and should return an object of default properties for new instances.
128
+
129
+
-`data {Object}` - The instance data
130
+
- An `utils` object containing these props:
131
+
-`store` - The vuex store
132
+
-`Models {Object}` The `globalModels` object, which is the same as you'll find inside a component at `this.$FeathersVuex`.
133
+
134
+
66
135
## Creating instances
67
136
68
137
The [FeathersVuex plugin for Vue](./vue-plugin.md) allow convenient access to all Model constructors. You can create a Model instance by getting a reference to a Model class from the `$FeathersVuex` object:
Do you find yourself spending time writing defaults into your form components? Maybe you wrote a utility for yourself or found one on npm that can do the trick for you. That's a thing of the past. You can now specify the default values for Model instances by using the `instanceDefaults` option when using the service plugin. Here's what it looks like:
With the above configuration, when you create a [`Todo` instance](./model-classes.md), it will have the attributes provided as `instanceDefaults`. This is especially useful for binding to form data. If the attributes aren't defined while binding, the automatic Vue reactivity won't work. Remember to not set any of the attributes to `undefined`, but instead use `null`. If not, the reactivity breaks, and you might spend some time wondering why your form is broken.
142
-
143
-
### A Word Of Warning
144
-
145
-
One thing to be aware of when using `instanceDefaults` as an object is that values can persist between instances and mutate separate instances. For example, when including an `Array`, changes made to one instance will affect any other instances of this model too.
146
-
147
-
Using `instanceDefaults` as an object will be deprecated in the next major version of `feathers-vuex` so it's best to stick to the function option below.
148
-
149
-
## instanceDefaults | Function <Badgetext="1.7.0+" /> <Badgetext="recommended"type="warn"/>
150
-
151
-
A much more powerful API is available when you provide `instanceDefaults` as a function. The function will be called with the following arguments and should return an instanceDefaults object.
152
-
153
-
-`data {Object}` - The instance data
154
-
- An `utils` object containing these props:
155
-
-`store` - The vuex store
156
-
-`Model {FeathersVuexModel}` - The current Model (the same as the current instance's constructor)
157
-
-`Models {Object}` The `globalModels` object, which is the same as you'll find inside a component at `this.$FeathersVuex`.
158
-
159
-
This API allows for a lot of flexibility. In the below example, each todo instance has a `get user` property. If the instance has a `userId`, the correct user record will automatically be fetched from the store.
todo.save() // --> Creates the todo on the server.
@@ -220,12 +202,12 @@ As mentioned, `save` performs either `create` or `patch`, but you can use the `p
220
202
221
203
### `instance.create(params)`
222
204
223
-
The `create` method is a shortcut for calling the `create` action (service method) using the instance data. The `params` argument will be used in the Feathers client request. See the [Feathers Service](https://docs.feathersjs.com/api/services.md#service-methods) docs, for reference.
205
+
The `create` method calls the `create` action (service method) using the instance data. The `params` argument will be used in the Feathers client request. See the [Feathers Service](https://docs.feathersjs.com/api/services.md#service-methods) docs, for reference.
224
206
225
207
You might not ever need to use `.create()`, but can instead use the `.save()` method. Let `feathers-vuex` call `create` or `patch`.
226
208
227
209
```js
228
-
const { Todo } =this.$FeathersVuex
210
+
const { Todo } =this.$FeathersVuex.api
229
211
constdata= { description:'Do something!' }
230
212
consttodo=newTodo(data)
231
213
@@ -234,12 +216,12 @@ todo.create() // --> Creates the todo on the server using the instance data
234
216
235
217
### `instance.patch(params)`
236
218
237
-
The `patch` method is a shortcut for calling the `patch` action (service method) using the instance data. The instance's id field is used for the `patch` id. The `params` argument will be used in the Feathers client request. See the [Feathers Service](https://docs.feathersjs.com/api/services.md#service-methods) docs, for reference.
219
+
The `patch` method calls the `patch` action (service method) using the instance data. The instance's id field is used for the `patch` id. The `params` argument will be used in the Feathers client request. See the [Feathers Service](https://docs.feathersjs.com/api/services.md#service-methods) docs, for reference.
238
220
239
221
Similar to the `.create()` method, you might not ever need to use `.patch()` if you just use `.save()` and let `feathers-vuex` figure out how to handle it.
@@ -251,12 +233,12 @@ todo.patch() // --> Sends a `patch` request the with the id and description.
251
233
252
234
### `instance.update(params)`
253
235
254
-
The `update` method is a shortcut for calling the `update` action (service method) using the instance data. The instance's id field is used for the `update` id. The `params` argument will be used in the Feathers client request. See the [Feathers Service](https://docs.feathersjs.com/api/services.md#service-methods) docs, for reference.
236
+
The `update` method calls the `update` action (service method) using the instance data. The instance's id field is used for the `update` id. The `params` argument will be used in the Feathers client request. See the [Feathers Service](https://docs.feathersjs.com/api/services.md#service-methods) docs, for reference.
255
237
256
238
Use `.update()` whenever you want to completely replace the data on the server with the instance data. You can also set the `preferUpdate` option to `true` to make `.save()` call `.update()` when an id field is present on the instance.
@@ -266,10 +248,10 @@ todo.update() // --> Sends a `update` request the with all instance data.
266
248
267
249
### `instance.remove(params)`
268
250
269
-
The `remove` method is a shortcut for calling the `remove` action (service method) using the instance data. The instance's id field is used for the `remove` id. The `params` argument will be used in the Feathers client request. See the [Feathers Service](https://docs.feathersjs.com/api/services.md#service-methods) docs, for reference.
251
+
The `remove` method calls the `remove` action (service method) using the instance data. The instance's id field is used for the `remove` id. The `params` argument will be used in the Feathers client request. See the [Feathers Service](https://docs.feathersjs.com/api/services.md#service-methods) docs, for reference.
The `.clone()` method creates a deep copy of the record and stores it on `Model.copiesById`. This allows you to make changes to the clone and not update visible data until you commit or save the data.
There's another use case for using `.clone()`. Vuex has a `strict` mode that's really useful in development. It throws errors if any changes occur in the Vuex store `state` outside of mutations. Clone really comes in handy here, because you can make changes to the clone without having to write custom Vuex mutations. When you're finished making changes, call `.commit()` to update the store. This gives you `strict` mode compliance with little effort!
298
280
299
-
Finally, if for some reason you prefer to keep the copies in the Vuex store and use custom mutations for all update, you can set the `keepCopiesInStore` option to `true`. This will cause the copies to be stored in `state.copiesById`.
281
+
> Nonte: You could previously use the `keepCopiesInStore` option to keep copies in `state.copiesById`. In 2.0, this feature is deprecated and will be removed from the next release.
0 commit comments