Skip to content
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

Feature Request: A Bind decorator for class components #88

Open
HeshamMeneisi opened this issue Sep 12, 2020 · 0 comments
Open

Feature Request: A Bind decorator for class components #88

HeshamMeneisi opened this issue Sep 12, 2020 · 0 comments

Comments

@HeshamMeneisi
Copy link

I really like the idea of putting a proxy over the stores (vxm) and abstracting all the mutations and mapX decorators. I found your package while doing research on how to achieve this myself and decided to use it (nice work btw, very neat). However, in order to achieve 2-way binding, I realized I had to define getters and setters on the component like so:

get foo {
    return vxm.example.foo;
}
set foo(value: string){
    vxm.example.foo = value;
}

Not bad given the usual boilerplate required to do that, but I decided to go one step further and just define the store module on the component (would be nice to include this in README):

private example = vxm.example;

However, this meant that every time I need to use a field, I would have to address it with the full path (e.g. example.foo). So, I came up with the following decorator:

export function Bind(module: Record<string, any>, field: string) {
  return function(target: Vue, propertyKey: string) {
    const getter = function() {
      return module[field];
    };
    const setter = function(newVal: any) {
      module[field] = newVal
    };
    Object.defineProperty(target, propertyKey, {
      get: getter,
      set: setter
    });
  }
}

In the class component:

@Bind(vxm.example, "foo") private foo: string;

In the template:

<VTextField v-model="foo" />

This does the job but it's just too loose. There's no guarantee that the types are the same or that this field exists in the store at all so you will only find out you made a mistake during runtime. Any way to make it cleaner?

Ideally, it should be something like this:

@Bind(vxm.example.foo) private foo;

However, this requires that foo is passed by reference, which can only be achieved if there's a proxy over primitive fields and I assume this isn't exactly performance friendly (I might be wrong about this), so to dodge that maybe something like:

@Bind(vxm.example.bindable.foo) private foo;

Which can perhaps be achieved with an extending submodule?

What do you think? Just over-engineering or a nice feature to add? I haven't read your code yet so there might be a much easier way to do this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant