Skip to content
This repository has been archived by the owner on Feb 22, 2018. It is now read-only.

ng-change for <select> is invoked before the model is updated #399

Closed
RobertSzymacha opened this issue Jan 9, 2014 · 9 comments
Closed
Milestone

Comments

@RobertSzymacha
Copy link

I have following component template:

...
<select
    ng-change="ctrl.selectionChanged()"
    ng-model="ctrl.currentValue">
  <option value="aaa">aaa</option>
  <option value="bbb">bbb</option>
  <option value="ccc">ccc</option>
</select>
...

And the component's dart code:

...
String currentValue = "aaa";
void selectionChanged() {
  print("currentValue $currentValue");
}
...

After selecting "bbb" in the select, controller prints:

currentValue aaa

while it should print "currentValue bbb"

@ghost ghost assigned mhevery Jan 22, 2014
@mhevery
Copy link
Contributor

mhevery commented Feb 5, 2014

1ab385e can not reproduce, assuming no longer an issue.

@mhevery mhevery closed this as completed Feb 5, 2014
@sodawong
Copy link

I got the same issue as RobertSzymacha even in Dart SDK version 1.2.0-dev.5.7.

@sodawong
Copy link

For temporary bug fix, I need to add a time delay of 1 ms as below to get the correct value:

import 'dart:async';
String currentValue = "aaa";
void selectionChanged() {
  new Timer(const Duration(milliseconds: 1), () {
    print("currentValue $currentValue");
  }
}

i.e. After selecting "bbb" in the select, controller prints: bbb

@mhevery mhevery reopened this Feb 19, 2014
@RobertSzymacha
Copy link
Author

Instead of adding 1 ms delay, you can simply run it in a Future. It's still a hack, but with less overhead (see https://www.dartlang.org/articles/event-loop/).

import 'dart:async';
String currentValue = "aaa";
void selectionChanged() {
  new Future(() {
    print("currentValue $currentValue");
  });
}

@zoechi
Copy link
Contributor

zoechi commented Mar 19, 2014

same issue on http://stackoverflow.com/questions/22509257

@mhevery
Copy link
Contributor

mhevery commented Apr 9, 2014

mhevery@f26e3ba

The issue is that ng-change and input directive can be registered in any order.
This makes it possible for on-change event to execute before input event gets a
chance to run.

Changing from ng-change to on-change fixes the issue, since events are on-change
has to bubble to EventHandler before it can run. This is not quite right, since if
EventHandler is registered on the same element as input element, then again we don't
know which event listener will run first.

The separate registration model also means that apply() gets run for each element,
which is wasteful.

A proper way to fix this is for EventHandler to handle both the change event for
both on-change as well as for input element. This means that EventHandler needs to
be able to call listener function on InputElement. The only way to do that is for the
EventHandler to attach the listener function to the Expando. Currently we are favoring
the NgElement over NgPorbe object. So NgElement needs to have a list of listeners from
underlying directives which are not expressions on the DOM (as is on-change). These
listeners need to be stored in NgElement and retrieved by the EventHandler when event
fires.

@mhevery mhevery assigned mvuksano and unassigned mhevery Apr 9, 2014
@mhevery mhevery modified the milestones: 0.9.11, v0.9.7 Apr 9, 2014
@vicb vicb modified the milestones: 0.10.0, 0.9.11 Apr 16, 2014
@mhevery mhevery modified the milestones: 0.12.0, 0.10.0 Apr 17, 2014
mvuksano added a commit to mvuksano/angular.dart that referenced this issue May 6, 2014
NgElement uses EventHandler to register event listeners. Event Handler
exposes API to register callbacks, release them as well as a method
(walkDomTreeAndExecute) that is used (by TestBed.triggerEvent) to
emulate even bubbling when DOM tree is not attached to document.body.
ElementProbe is also extended to allow attaching additional
listeners. This can be used by different components to
programatically attach event handlers (see InputSelectElement and it's
change event handler).

Closes dart-archive#399
@vicb vicb modified the milestones: 0.12.0, 0.11.0 May 8, 2014
@chirayuk chirayuk modified the milestones: 0.13.0, 0.12.0 Jun 3, 2014
mvuksano added a commit that referenced this issue Jul 14, 2014
NgElement uses EventHandler to register event listeners. Event Handler
exposes API to register callbacks, release them as well as a method
(walkDomTreeAndExecute) that is used (by TestBed.triggerEvent) to
emulate even bubbling when DOM tree is not attached to document.body.
ElementProbe is also extended to allow attaching additional
listeners. This can be used by different components to
programatically attach event handlers (see InputSelectElement and it's
change event handler).

Closes #399
@vsavkin vsavkin modified the milestones: 0.14.0, 0.13.0 Jul 24, 2014
mvuksano added a commit that referenced this issue Aug 13, 2014
NgElement uses EventHandler to register event listeners. Event Handler
exposes API to register callbacks, release them as well as a method
(walkDomTreeAndExecute) that is used (by TestBed.triggerEvent) to
emulate even bubbling when DOM tree is not attached to document.body.
ElementProbe is also extended to allow attaching additional
listeners. This can be used by different components to
programatically attach event handlers (see InputSelectElement and it's
change event handler).

Closes #399
mvuksano added a commit that referenced this issue Aug 14, 2014
NgElement uses EventHandler to register event listeners. Event Handler
exposes API to register callbacks, release them as well as a method
(walkDomTreeAndExecute) that is used (by TestBed.triggerEvent) to
emulate even bubbling when DOM tree is not attached to document.body.
ElementProbe is also extended to allow attaching additional
listeners. This can be used by different components to
programatically attach event handlers (see InputSelectElement and it's
change event handler).

Closes #399
@rkirov rkirov modified the milestones: 0.14.0, 0.15.0 Aug 22, 2014
@rkirov
Copy link
Contributor

rkirov commented Oct 10, 2014

PR is too old to be useful and we have no immediate plans to work on this.

@rkirov rkirov closed this as completed Oct 10, 2014
@Subhapriya
Copy link

I also have the same problem.

@dsl400
Copy link

dsl400 commented Mar 25, 2016

model update will not trigger change on my guess is that it has to do something with selected="true" <option selected="true" ng-repeat="st in stations | orderObjectBy: 'StationName' | filter: {isAirport:true}" value="{{st._id}}">{{st.StationName}}</option>

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

No branches or pull requests