I'm new to angular and I'm confused about needing to use $scope.$watch in the this very simple plunk in order to see my selection change. If the $watch is removed, the alert is not triggered. Should selection not be automatically bound when I select something and then the change event should trigger a digest and automatic watch?
You don't need $scope.$watch. You can simpy use ngChanged directive.
From Docs (emphasis mine)
Evaluate the given expression when the user changes the input. The expression is evaluated immediately, unlike the JavaScript onchange event which only triggers at the end of a change (usually, when the user leaves the form element or presses the return key). The expression is not evaluated when the value change is coming from the model.
DEMO
Related
I am using $dirty to check the changes in a form ,but if i type something in the input box and remove it, the $dirty is still true.Is there any solution or it will work like this.
That is by design. Any form becomes $dirty whenever the user interacts with it, and you cannot undo the interaction event. Though you can restore defaults, that is clearly not the same.
Consider using $watch to check whether new value is different from the default one, and $setPristine() to clear user input.
$dirty means The field has been modified one more time. for compare your model by your previous model you can use $watch in controller.
if your field is empty you have a solution must set required attribute and in your input tag and use below code set ng-validate of your form to novalidate and then use below code for compare:
formName.inputName.$dirty && formName.inputName.$error.required
$Dirty refers to the form field is modified and you want to check using $pristine
I'm building a questionnaire out of directives which show the correct input based on certain expectations. Those expectations (including any formerly given input from the user) comes from a parent $scope. Everything is set up in the link function of AngularJS's directive definition object
Where things go wrong is when using md-checkbox: the ng-model of the checkbox inside the directive is set to true, the md-checkbox is still false. I can confirm that by adding a simple input type="checkbox" with the same ng-model property, the simple checkbox is checked, whereas the md-checkbox isn't.
Whenever I click on the md-checkbox twice, it does get checked. So I gather that there is something wrong with the binding. I built a CodePen which demonstrates it. The code inside the pen is almost taken verbatim from my source code
Stuff that I already tried:
Using $scope.$apply() after handling all (DOM) logic in the link function
Idem but with $scope.$digest()
Setting a $timeout with no delay (as way of a 'safe' $apply())
Even going so far as to store the current answer (true or false) in a variable, setting the ng-model property to undefined, and then setting it back to the stored value, all inside a $timeout
I'm at loss here, it looks like something simple given the fact that all the other inputs have their correct data in it.
Replace class with ng-class because ng-class lets you to dynamically bind the class to the element
Depending on your codepen the problem is class="md-checkbox-{{expression}}". I forked your codepen. You can use ng-class. I think this is a bug.
I am facing one problem with textbox in angularjs.
When I am updating textfield data by some way(Like clicking button) then ng-change is not working. Please check plnkr
[https://plnkr.co/edit/32eE0ejSNBTkWJ4LVErR?p=preview][1]
When I am updating first name on button click ng-change is not firing, but when i am changing first name in textfield ng-change is getting fired
This behaviour is intended. It says this in the official documentation:
The ngChange expression is only evaluated when a change in the input
value causes a new value to be committed to the model.
It will not be evaluated:
if the value returned from the $parsers transformation pipeline has
not changed
if the input has continued to be invalid since the model will stay null
if the model is changed programmatically and not by a change to the input value
source
In your case, the last item in that list applies.
if the model is changed programmatically and not by a change to the input value
You'll have to use a watch in this case.
So I'm trying to build a custom autocomplete dropdown for a text input. To do it, I am listening for the keydown event and if it's an up or down arrow press, I'm setting a $scope.arrowSelectedItem variable to the proper one in the list. (As a side note, all the functionality works as far as selecting an item from the list that pops up. All I'm trying to do is highlight the current one that they've marked with the up/down arrows).
On the markup side, the items in the autocomplete list are output with ng-repeat, with ng-repeat="item in itemList". The ng-class expression I'm using is ng-class="{highlighted: item === arrowSelectedItem}". I know that the $scope.arrowSelectedItem is being updated on each arrow press by using console.log, but for some reason the class isn't being updated to the list item properly.
What I've found is that after the first time of hitting an arrow key, if I make the text input box lose focus, then the class is added. Then if I click back in the box, move the arrow to select a different item, click out of the input box, then click back in, the class is added to the new one. I know that sounds weird, but that's what I've found.
What I'm not sure about is why the ng-class expression isn't being evaluated on every arrow key press. Does anyone have any ideas why?
The answer here is that "raw" DOM events which fire outside of one of angular's built in directives (such as click events via ng-click etc) will not trigger a $digest cycle update. Until this happens the $scope properties will not be updated.
If you are in a position where you are listening for DOM events by using another framework, or simply using addEventListener(), you will need to let angular know about any changes by using $scope.$apply(), or by wrapping the code in a $timeout().
If you do this in your event handler, angular will trigger a new $digest cycle update for every keypress and your new scope values will propagate to the view.
Introduction
I' m writing checkbox tree directive using angular. Part of the behaviour is when I check checkbox in the middle of the tree, I need to unset all ancestor checkboxes and set all descendant checkboxes (see screenshot, transparent checkboxes are unchecked in fact).
https://www.dropbox.com/s/yx1bzqsamunmjpx/Screenshot%20from%202014-08-25%2018%3A39%3A44.png?dl=0
I'm using:
itemScope.$watch('checked', function setCheckboxes(newValue, oldValue) { ... });
For descendants everything works fine. I forEach child checkboxes and set them a new value, which in turn fires events for their descendants and so forth.
Problem is with ancestors. If I set parent checked value to false, it triggers event which sets all children to false which is not desired.
Question starts here:
I need to find a way to update (ancestor checkbox) model without firing event I subscribed with $watch. I know one way to wrap new value assignment in setTimeout(fn, 1), but I think it's not cool. What's the correct way of doing this?
Thanks!
You could use the ngChange directive on the checkbox to kick off the correct behavior, rather than $scope.watch. From the docs:
The ngChange expression is only evaluated when a change in the input value causes a new value to be committed to the model.
It will not be evaluated:
if the value returned from the $parsers transformation pipeline has not changed
if the input has continued to be invalid since the model will stay null
if the model is changed programmatically and not by a change to the input value