-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initializing observables in constructor. #563
Comments
@jeffijoe, you can rewrite class ViewModel {
constructor (model) {
const { name, email } = model;
extendObservable(this, { model, name, email });
}
save () {
this.model.name = this.name
this.model.email = this.email
}
} |
@andykog ah, because that does the init? That's not a very pretty solution though, as I would like to continue using decorators with actual default values |
I think constructor (model) {
mobx.extras.allowStateChanges(true, () => {
this.model = model
this.name = model.name
this.email = model.email
})
} Should work. Maybe a more neat solution is to allow state changes to observables that have no observers (and maybe also: that where created in the current tick) |
@mweststrate thanks for the workaround :) I think it makes sense to allow changes for observables created in the current tick as well. :) |
Definitely makes sense. If I could vote, I would vote for that :) |
@mweststrate are there plans to make @usestrict as a decorator (for single-use ?)
|
@devdoomari no, but mobx-state-tree will offer a similar concept; it's action will only allow to change the owning object (or descendants) |
If there is a champion willing to implement these two features, he is more then welcome!
I think the first one should be quite easy, for the second one, no clue yet, maybe that isn't easily, cleanly doable :) cc: @capaj @urugator @antitoxic @jeffijoe @asterius1 @andykog @delaetthomas |
I will have to miss this one. Life is pushing stuff :) new job, flat and so on. A mobx internals crash course would be useful if I have to dig in at some point :) |
See also #798. |
Proposal to change the state modification guard to the following behavior: Changing a piece of state is only allowed if any of the following conditions are met:
For reference, the current behavior of the guard is: |
Just released 3.1.0, in which constructors no longer are required to wrap their assignment in actions |
@mweststrate What's up :) So does that mean all constructors are in fact implicit actions? |
No, in actions you can modify any observable, in constructors (or generally anywhere outside of action) you can modify only unobserved observables. |
Well, when I'm modifying an observable value from a constructor of the class it belongs to, MobX tracks and propagates the change to observers. |
@brunolm Is #1507 (comment) relevant? |
@urugator if I set to import { Component } from '@angular/core';
import { AppStoreService } from '../app-store.service';
@Component({
selector: 'app-about',
templateUrl: './about.component.html',
styleUrls: ['./about.component.scss'],
})
export class AboutComponent {
constructor(
public store: AppStoreService,
) {}
updateTitle() {
// when strict --- this is blocked
// when true --- should not be allowed, but is
this.store.about.title = 'some random string';
// action to change title
// this.store.about.randomTitle();
}
} |
@brunolm Is |
@urugator hmm I see, so what I want is import { Injectable } from '@angular/core';
import { action, observable } from 'mobx-angular';
@Injectable({
providedIn: 'root',
})
export class AboutStoreService {
@observable title: string;
constructor() {
this.initialize();
}
@action
private initialize() {
this.title = 'about:hello world';
}
@action
randomTitle() {
// tslint:disable-next-line:no-magic-numbers
this.title = Math.random().toString(32);
}
} |
Also you can do initializing inside import { observable, action, runInAction } from 'mobx';
class Steps<StepsType> {
@observable
public activeStep: StepsType;
constructor(activeStep: StepsType) {
runInAction(() => {
this.activeStep = activeStep;
});
}
@action
public goToStep = (step: StepsType) => {
this.activeStep = step;
};
}
export default Steps;
|
I've got a use case where I could use some advice as to how I should go about this "the MobX way".
Note: This is not even close to my actual code, but the problem is there
The problem arises when the transformer is invoked; I am not allowed to initialize the viewmodel state. I know I could just write getters and setters, but that's too much boilerplate, and the viewmodel has more complicated state as well.
Whats the best way to approach this without breaking the MobX guidelines? Or is there an escape hatch for the cases where I know what I am doing? 😄
Question is if I can allow state changes for observables that were created during the current "execution"? I would never modify existing state, but I should be able to initialize new state, right?
The text was updated successfully, but these errors were encountered: