Closed rseyferth closed 4 years ago
Would something like this work for you?
function setModelAttribute<M extends AnyModel>(
this: M,
key: keyof ModelInstanceData<M>,
value: ModelInstanceData<M>[typeof key]
): void {
;(this as any)[key] = value
}
@model("P2")
export class P2 extends Model({
y: prop(0),
}) {
@modelAction
addY = (n: number) => {
this.y += n
return this.y
}
@modelAction
set = setModelAttribute
}
test("set", () => {
const p2 = new P2({})
p2.set("y", 5) // strongly typed
expect(p2.y).toBe(5)
})
Alternatively I think I could make it so prop
/ tProp
can have a parameter to make assignations be under an action automatically for that particular property, something like:
@model("P2")
export class P2 extends Model({
y: prop(0, { setAction: true }),
}) {
}
so p2.y = 5
is already under an action automatically
Would need to think how to make it so arrays support it too with push
, etc. and objects too though.
Yes, that first approach is exactly what I need, brilliant!
Another thing I came across is that you can't instantiate an 'empty' record, to use in a 'new user'-form for example, without making all the attributes maybeNull
or something similar. I really like the Draft flow, but would it be possible to add something like a "Concept" option, that functions similar to Partial<Model>
in typescript, so all attributes are automatically allowed to be undefined inside the ConceptDraft, until you try to commit it.
Anyway, thanks for the quick response on the setAttribute thing!
https://github.com/xaviergonz/mobx-keystone/pull/129
That PR includes a applySet/applyDelete/applyCall that should also help if you don't want to put a "set" function into every model.
Also it includes a setterAction
as model property option to automatically create setters.
When using models with a lot of attributes in forms it can become kind of tedious to create all the setters for each attribute. It would be nice if there were a generic setter method, that would allow you to set any attribute.
Currently I use the following workaround, through snapshots:
Or is there another way or approach to do this that I'm not seeing?