aurelia / framework

The Aurelia 1 framework entry point, bringing together all the required sub-modules of Aurelia.
MIT License
11.75k stars 623 forks source link

Change functions not firing when value changed with Aurelia Store #906

Closed NRKirby closed 6 years ago

NRKirby commented 6 years ago

Whilst this bug only happens when I change state using Aurelia Store I feel like this could be an issue in the framework. If this issue should be raised somewhere else could you advise where please?

I'm submitting a bug report

Current behavior:

When a value is changed on a property using Store, change events are not firing.

In my view model I have 2 property change functions defined:

@bindable() parameter: Parameter;

parameterChanged() {
    this.validate();
}    

valueChanged() {
    this.validate();
}

In my view I have:

<select value.bind="parameter.value"
        change.delegate="valueChanged()"
        class.bind="isValid ? '' : 'has-error'">
        ... 
</select>

I change the value of the parameter via an action like this using Store:

export async function changeValue(state: State, value: string) {
    const newState = Object.assign({}, state);
    newState.setup.parameter.value = value;
    return newState;
}

When use Store to change the value of the select parameter.value, the value changes but neither property change functions fire.

Expected/desired behavior:

At least one of the property change functions should fire.

AshleyGrant commented 6 years ago

You are binding to the element's change function, not the property's change function. You are seeing the expected behavior, even if it might be somewhat confusing. You have to understand that form element change events do not fire when the value of the element is changed by JavaScript code, and the Aurelia Framework, at the end of the day is "just JavaScript."

Given that you are using Aurelia Store, the correct place for this code would be in a state changed subscription.

NRKirby commented 6 years ago

Hi @AshleyGrant , thanks for your reply.

You are binding to the element's change function, not the property's change function

Isn't the parameterChanged() function the change function for the property parameter? I would have expected this function to fire when the value changes. Or am I misunderstanding something?

Thanks again for taking the time to help me with this.

Edit: we just tried the subscription which works perfectly:

@connectTo({
    selector: {
        parameter: (store) => store.state.pipe(pluck("parameter"))
    }
})

parameterChanged() {
    this.validate();
}
AshleyGrant commented 6 years ago

Isn't the parameterChanged() function the change function for the property parameter?

Yes, but parameter isn't changing. the value property of parameter is changing.