Incompatibility between ng-value and ng-model [duplicate] - angularjs

As far as i understood ng-model sets the value for that particular element in which the model is been assigned.
given that how is ng-value different from ng-model?

It works in conjunction with ng-model; for radios and selects, it is the value that is set to the ng-model when that item is selected. Use it as an alternative to the 'value' attribute of the element, which will always store a string value to the associated ng-model.
In the context of radio buttons, it allows you to use non-string values. For instance, if you have the radio buttons 'Yes' and 'No' (or equivalent) with values 'true' and 'false' - if you use 'value', the values stored into your ng-model will become strings. If you use 'ng-value', they will remain booleans.
In the context of a select element, however, note that the ng-value will still always be treated as a string. To set non-string values for a select, use ngOptions.

Simple Description
ng-model
Is used for two way binding of variable that can be available on scope as well as on html.
which has $modelValue(value reside in actual scope) & $viewValue (value displayed on view).
If you mentioned on form with name attribute then angular internally creates validation attributes for it like $error, $valid, $invalid etc.
Eg.
<input type="text/checkbox/radio/number/tel/email/url" ng-model="test"/>
ng-value
Is used to assign value to respective ng-model value like input,
select & textarea(same can be done by using ng-init)
ng-value does provide good binding if your are setting ng-model value through ajax while writing value attribute doesn't support it
Basically meant to use for radio & option tag while creating select options dynamically.
It can only have string value it, it doesn't support object value.
HTML
<input
[ng-value="string"]>
...
</input>
OR
<select ng-model="selected">
<option ng-value="option.value" ng-repeat="option in options">
{{option.name}}
</option>
</select>
...

A good use for ng-value in input fields is if you want to bind to a variable, but based on another variable's value. Example:
<h1>The code is {{model.code}}.</h1>
<p>Set the new code: <input type="text" ng-bind="model.code" /></p>
When the user types in the input, the value in the title will be updated. If you don't want this, you can modify to:
<input type="text" ng-value="model.code" ng-bind="model.theNewCode" />
theNewCode will be updated, but code will remain untouched.

According to the https://docs.angularjs.org/api/ng/directive/ngValue, ngValue takes an "angular expression, whose value will be bound to the value attribute of the input element".
So, when you use ng-value="hard", it is interpreted as an expression and the value is bound to $scope.hard (which is probably undefined).
ngValue is useful for evaluating expressions - it has no advantage over value for setting hard-coded values. Yet, if you want to hard-code a value with ngValue, you must enclose it in '':
ng-value="'hard'"
ng-model is intended to be put inside of form elements and has two-way data binding ($scope --> view and view --> $scope) e.g. <input ng-model="val"/>.
or you can say The ng-model directive binds the value of HTML controls (input, select, textarea) to application data.

The documentation clearly states that ng-value should not be used when doing two-way binding with ng-model.
From the Docs:
ngValue
Binds the given expression to the value of the element.
It can also be used to achieve one-way binding of a given expression to an input element such as an input[text] or a textarea, when that element does not use ngModel.
— AngularJS ng-value Directive API Reference
Instead, initialize the value from the controller:

Related

ngChange on input changed by a select

I have a simple select input field where the user can choose an option:
<select class="form-control" id="calc-masterbatchCode"
ng-options="masterbatch as masterbatch.code for masterbatch in masterbatches"
ng-model="$parent.materialTAB.selectedMasterbatch">
</select>
as you can see the selectedMasterbatchobject is stored in a parent controller.
Then i have a disabled input field in the order to show the property of the selectedMasterBatch:
<input type="text" class="form-control" id="calc-masterbatchPercentage"
ng-model="$parent.materialTAB.selectedMasterbatch.percentage"
ng-change="onMasterbPercentageChange()">
It works, but the problem is the ngChangedirective:
because it doesn't fire the onMasterbPercentageChange function when the user select another masterbatch.
The only way to fire that function is to type something manually into the calc-masterbatchParcentageinput field.
My goal is:
the user select a masterbatch, then he can see the masterbatch's property (the percentage) into the disabled input field and, when this one change, the onMasterbPercentageChangefunction is fired.
ngChange directive doesn't work on disable/readonly inputs, because it's only evaluated when a change in the input value causes a new value to be committed to the model. So, since you're changing the value programmatically and not typing anything to this model, it doesn't calls ngChange
Here is more one part extracted from docs:
ngChange 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
So, to achieve what you want you must move your ng-change to your <select>.
I hope it helps.

AngularJS: selecting option from dropdown menu

Here is my code:
<select class="form-control" name="author" ng-options="author as author.fullname for author in authors" ng-model="author" ng-required="true"></select>
How would I change selected value from controller?
Simply set the $scope.author to whatever author you want, for example:
$scope.author = $scope.authors[2];
Here is an example jsBin
Or look up the author some how (by name, id?) and set the $scope.author or whatever to that value.
Angular works on "2-way binding". ng-model="author" binds your dropdown to $scope.author so a change in either the dropdown or the controller will reflect on both places, hence the binding.
So from your ng-options I'm assuming you have an array called authors of type author so in your controller simply
$scope.author = $scope.authors[0];
Remember that in the controller you need the $scope. before the variable and in the html ng-model or other ng directives you do not need the $scope. prefix

ng-show and ng-model can't work together on the same $scope variable

I am trying to have a span element show some $scope variable only if it is not null or empty.
I know i can accomplish this with only ng-model, but i don't understand they this won't work:
<span ng-show="x !== null" ng-model="x"></span>
or something similar to this.
ng-model is for two-way binding (as #MK Safi said above), which means its for elements that both display values and allow users to change those values. Probably not a <span/>...
If you're just looking to show the value of the model in the span, use ng-bind or expression syntax - {{ x }}
This way, ng-show should work properly to add the relevant CSS styles as x changes.
E.g.:
<span ng-bind="x" ng-show="x !== null"></span>
or
<span ng-show="x !== null">{{ x }}</span>
ng-model is used mostly for input, textarea, and select elements. It's not used on span, div, or p elements, etc.
From Angular documentation on ngModel
The ngModel directive binds an input,select, textarea (or custom form control) to a property on the scope using NgModelController, which is created and exposed by this directive.
Yes, as MK Safi says ng-model is only used to bind inupts to $scope variables. This should work though:
<span ng-show="x !== null">{{ x }}</span>
Just use the templating engine to display the value in $scope.x

ng-options and ng-bind not working with objects and strings

I have a drop down bound to ng-options (which uses an array of objects)
and ng-bind (which uses a string). This doesn't work because object comparison fails. Is there a workaround for this?
<select class="form-control"
ng-model="Person.Gender"
ng-options="a.name for a in dropdowns.gender">
</select>
Thanks
If I'm not mistaken what you want is to bind the name property to the person.gender property of the $scope. What you need to do is:
<select class="form-control"
ng-model="Person.Gender"
ng-options="a.name as a.name for a in dropdowns.gender">
</select>
The first part defines what is actually stored in the ng-model and the second part how is going to display, in this case both displayed value and model value are the same.
Working fiddle: jsfiddle

AngularJS : How to get value and label of a select?

I'm using a select tag with a ng-model attribute. I get the value of the selected element in ng-model. How is it possible to also get the label of the selected element.
I would like to retrieve both the label and its value. Thanks.
I'm guessing you are either using ng-repeat to create your choices, or typing them manually in the template. It is possible if you set your labels and values in the same model. If you have:
$scope.choices = {
"choiceone" : "The first Choice",
"choicetwo" : "The second Choice",
"choicethree" : "The third Choice"}
You can implement them like so:
<select ng-model="choice">
<option ng-repeat="(key, value) in choices" value="{{key}}">{{value}}</option>
</select>
However, this isn't the best way to use the select directive (assuming this is what you are doing). The select directive has a ng-options attribute that defines both value and label, in a cleaner fashion. I've edited the doc's example Plunkr on this subject, including a example usage of a ngRepeat here: http://plnkr.co/edit/sjQuhlgBh8WWJJoaSSMG?p=preview
Check here for the docs on the ng-options attibute: http://docs.angularjs.org/api/ng.directive:select

Resources