1

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.

Community
  • 1
  • 1
Error
  • 815
  • 1
  • 19
  • 33

1 Answers1

2

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

Community
  • 1
  • 1
Claies
  • 22,124
  • 4
  • 53
  • 77
  • What if I have isolated scope in directive. For instace: HTML: And I want, base on otherdata value add multiple directives. Because of that, I have isolated scope in common-things directive, and in that case, ng-model (el.val) is not updated as I write something inside input tag. – Error Mar 29 '17 at 06:20
  • if you make the scope on the input isolate, then not even your `selects` will bind to the element. If it is necessary to make the scope on an element isolate, then the directive that manages that element must take **total** responsibility for the data being used on that element; one way to accomplish this would be to bind `ng-model` to the `scope` in the directive. – Claies Mar 29 '17 at 06:28
  • Can i make it without isolated scope? What I am trying to do is: based on properties of passed data to directive (attribut "otherdata" on input) I want add other directive to that field. For examply if somedata.required=true, I want add my-required directive. Aditionally, I want add html tag after my input with following behaviour: I want it to be displayed if some function (from parent scope) evaluates to true. Because of that, I have isolated scope, I don't know how else pass function with parameters to directive and make that function to be called when user change input value – Error Mar 29 '17 at 09:56
  • it seems like you are trying to over-engineer this solution. what does `my-required` do that the normal `required` wouldn't accomplish? also, if you want a span after the input, then you probably should either have the span in the HTML separately and use `ng-if` or `ng-show`. If those don't work, your next best option would be to make a "wrapping" directive, and use transclusion to include the `input` without having the input be the actual target of the directives. – Claies Mar 29 '17 at 14:29