We have a lot of issues with change detection. If user changes a value in select, change event is fired and some magic happens. But value can also be changed from view model logic without user input and then change event and its magic is fired as well. But this magic should only be executed if user changes input value on model view. We have absolutely no clue how to detect if change is fired by user input or automatically from view model.
// view model
public selectedValueChanged(): void {
//this magic must only be executed if 'selectedValueChanged' is user changes 'selectedValue' on model view
//but it's also executed if 'selectedValue' is changed by some view model logic.
this.executeMagic();
}
public selectedValue: string;
public get selectedValueInView(){
return this.selectedValue;
}
public set selectedValueInView(val){
this.selectedValue = val;
this.selectedValueInViewChanged()
}
public selectedValueInViewChanged(): void {
//this magic must only be executed if 'selectedValueChanged' is user changes 'selectedValue' on model view
//but it's also executed if 'selectedValue' is changed by some view model logic.
this.executeMagic();
}
constructor() {
// there is probably something we can do in value converter to avoid this line
this.myCallback = this.myCallback.bind(this);
}
myCallback(newValue) {
}
Definitely an alternative, although still does not cover catching UI changes on bindable properties of custom elements. I figured two options, first is good old suppress flags, second tapping into binding itself, replacing updateTarget function.
@MaximBalaganskiy I might missed your point, but this should work on custom element with two-way binding. Kukks’s method should work with custom element too.
If you have a SomeElement has bindable prop value, you can use <input value.bind="value | onSet:cb"> in its template and have a cb() in SomeElement class.
When an element has a non text property, say it’s an autocomplete with an object value, you can’t just bind a dummy input to it, yet you need to differentiate an external change from the internal change
You are in the element’s view model code and have no control over how a customer binds to it. How do you differentiate a change from ui? Flags or tap into bindings.
I’d love to see an example…
We are talking about input right?
So either you have it inside your component… and can do what you want with it.
Or it is external to you and it should not matter how the change came in.
Otherwise it’s tight coupling IMO.
Let’s say we’ve got an <autocomplete value.two-way="someObject"></autocomplete>
Most of the time someObject will be set by the component upon selecting an option in a dropdown. But also the selected value will be set by a external user of an element. Inside the component’s code these assignments might need to be differentiated.