Add directives from directive in AngularJS but keep ng-model binded - javascript

This question is linked to following question:
Add directives from directive in AngularJS
In suggested answer, there's problem that ng-model is not updating because element is being compiled in directive.
What I expected is that, after I change select option, ng-model will be binded to selected item, but it's not.
Is there any way to fix it?
Plunker: http://plnkr.co/edit/Tw1Pbt?p=preview
Specificly:
<select ng-options="s for s in selects" ng-model="el" common-things>
<option value=""></option>
</select>
{{el}}
Here ng-model (el) has always same value, no matter what option I choos from select
Same problem is if I have isolated scope inside directive, for instance:
<input type=text common-things ng-model="el.val" otherdata="something"/>
I eexpect, as I write something inside input, that {{el.val}} would have that value, but it's not being updated.

Your additional directive creates a new scope for the <select> element. Due to JavaScript Prototype Inheritance, the property el ends up on the directive's scope rather than the parent controller's scope. This is a common pitfall, and a major reason to always use a dot in angular bindings.
The quick fix for this is to define el on the main controller as an object, and set a property of the object.
$scope.el = {};
$scope.el.val=2;
<select ng-options="s for s in selects" ng-model="el.val" common-things>
Demo

Related

How do i check html binding before create directive angularjs

A page, i called custom select-box directive to show Month and that directive need some arguments:
<custom-select-box
id="month"
model="month"
model-required
model-name="month"
options="month.value as month.name for month in months"
aria-label="{{month.name}}">
<option value="">{{'dcl-spa.components.claim-and-link.month.mm'|translate}}</option>
</custom-select-box>
But when i direct to this page or refresh, the argument {{'dcl-spa.components.claim-and-link.month.mm'|translate}} in <option> can not bind to html, just show the key dcl-spa.components.claim-and-link.month.mm on page.
The directive custom-select-box can not be change.
So what should i do on this case?
Thanks
The option markup should be inside the custom-select-box directive template.

Why does Angular not update the DOM by adding a 'selected' attribute to an <option> tag within ng-options when it correctly updates the model?

Using Angular 1.2.29 when I build a <select> with ng-options it appears on the surface to work as expected, when I select an option the model is updated, and visually the <select> indicates that the newly selected option has been chosen.
However, when using Developer Tools to view the mark-up I can see that the option tags are not updated, specifically the selected attribute is not removed from the previously selected option, nor is it added to the newly selected option.
<div data-ng-controller="MainController as main">
<pre> {{ main.test.item }} </pre>
<select
data-ng-model="main.test.item"
data-ng-options="item.label for item in main.test.items"
required="required">
<option value="" label="What do you want?"></option>
</select>
</div>
By setting the model this.test.item within the controller selected="selected" is added to the second option (with the label 'B'), however subsequent changes (made by using the select) do not update the mark-up accordingly.
angular
.module('myApp')
.controller('MainController', MainController);
function MainController () {
this.test = {};
this.test.items = [
{ label : 'A' },
{ label : 'B' },
{ label : 'C' }
];
// Pre-select the second item.
this.test.item = this.test.items[1];
}
It’s great that the model is kept up to date, but why does the mark-up remain unchanged?
What can be done to fix this so that it is updated to match the model?
https://jsfiddle.net/paulhhowells/4hmwhbe8/
Sorry, don't have enough reputation to post comments, apparently.
#paulhhowells I think the answer there still applies. To elaborate, the DOM has properties and attributes. Properties have the actual values that you care about, they'll update as you change the selection. What you're seeing when you see selected="selected" in the markup is the attribute selected. Attributes don't update as you change the selection, they exist in the markup to create the element, and are usually used to initialize the element's properites
EDIT: There's a better explanation in the jQuery documentation, take a look at the Attributes vs Properties section here.
The selected attribute should not be expected to be updated.
It is only used to indicate that the option it is on should be initially selected.
https://developer.mozilla.org/en/docs/Web/HTML/Element/option
Therefore, Angular does not update the DOM by adding a 'selected' attribute to an <option> tag within ng-options when it correctly updates the model, because it should not.

Angularjs - Access the value of dropdown in a nested ng-repeat

I'm can't access the value of the select in the controller when the select is inside an ng-repeat.
Here is the sample of Html (Everything display properly):
<tr ng-repeat="reservationItem in dataList">
<select ng-model="detail" ng-change= "haha($index)" ng-options="n for n in [1,2,3,42]" >
<option value="Choose"> Choose </options>
</select>
</tr>
``
In the controller, inside the function haha() I try to get the value of the selected dropdown:
$scope.haha = function(index){
console.log(index);
console.log($scope.detail);
}
The first console.log always show 0
The second console.log always shows undefined
Can someone tell me how to access the value of a select inside a nested from a controller. ?
Thanks
In this case, you have multiple detail ng-model. This confuses the angular, look at ng-model like an ID. you can't have duplicate. You would need to pull the select out, or attached detail to reservationItem ie. reservationItem.detail
Also, you won't need ng-change as angular autobinds that value to the model.

AngularJS - Data binding default value of html select

I would like to 'data bind' the default value of a html/jade select. Here is my select:
select#title.form-control(ng-model='newClient.title')
option(ng-repeat='title in titles', ng-selected='$first') {{title}}
The problem here is that if I don't touch the select, my newClient.title will be set as undefined and not the first title value. How can I do that without setting a default value in my controller?
You want to use ng-options to define the options, and then simply specify the ng-model for the first element. You don't have to worry about an ng-init.
<select ng-options="title for title in titles" ng-model='titles[0]'></select>
For reference, there's some pretty good documentation here.
You can use a ng-init directive.
ng-init="newClient.title = titles[0]"
Fiddle Here
in jade format:
select#title.form-control(ng-model='newClient.title',ng-init="newClient.title = titles[0]")
option(ng-repeat='title in titles', ng-value="title") {{title}}

Angular ng-model bound from nested ng-repeat

This must have been already done, and I am missing something about how Angular works on that point.
In short, I have <select ng-model><option ng-repeat/></select> and I don't know how to give it a default value at page load.
View:
<div ng-ctrl="MyCtrl">
<form ng-submit="submitChoice()">
<select ng-model='choice'>
<option ng-repeat='choice in choices' value='{{choice.id}}'>{{choice.id}}</option>
</select>
</form>
</div>
Way 1: When user updates the view (select the 'choice' he wants), the $scope used in MyCtrl gets it and I can perform whatever I want with it:
Way 2: But if, the other way round, I want to programmatically set the default value for the choices from the controller (at start), it can't change the value displayed:
function MyCtrl ($scope) {
$scope.submitChoice = function() {return;}; // Way1: OK!
$scope.choice = choice4; // Way2: Doesn't change the view!!
}
I guess it's because each element in ng-repeat has its own scope (fyi if I hardcode options in view instead of a ng-repeat, it works well).
In way 1 the inner scope selected by the use emits choice to the upper scope, if I understand well. But I have no idea how to do way 2.
Is it doable in a simple way? Is a directive necessary?
You would be better off using the ng-options directive with the select directive. Using select + ngRepeat has all sort of limitations and is better avoided. Is there any particular reason for generating options with ngRepeat?
If you could share more code (especially the structure of your data model) I might be able to provide more info.

Categories