NgModel requires $ parent if inside Transcluded html

I have a directive for an input field that uses a transition to take elements that are enclosed in a directive element that includes the ng-model attribute. After reading countless SO questions and Angular documentation to find out how to get ng-model in transidated html to synchronize with ng-model in my directive, I finally came across a trick to make it work. That is, use $parent , where ng-model is inside the input field. It's all fine and dandy, however, it seems awkward / hacks.

Plunker is shown here: http://plnkr.co/edit/gEje6Z2uuTs9DFPeCZfv

I tried to make this a little more elegant by combining with the intercept function in my link function like this:

`` ``

  var transcludedContent, transclusionScope; transcludeFn(scope, function(clone, scope) { //headerCtrl.$element.append(clone); transcludedContent = clone; transclusionScope = scope; console.log('scope form: ', scope); console.log('transclude form: ', clone); }); 

`` ``

Also shown in this Plunker: http://plnkr.co/edit/11k9LiA5hyi4xydWBo3H?p=preview

You might think that the forwarding function allows you to rewrite the scope of the transclusions to the scope of your directive, then the ng-model attributes will be linked and bound to the scope of the directives, however this is not so.

Despite the fact that $parent.<ng-model> works, it seems very hacky and can lead to errors, for example, if my directive was not used with a parent area that does not have a specific account object.

0
source share
1 answer

There are several ways to do this.

1) Display the variable account with =

http://plnkr.co/edit/DxsipWRj0AJe6Yi3bhse

JS:

 app.directive('formControl', [function(){ return { restrict: 'EA', template: '<div ng-transclude></div>{{account.name}}', scope: { account: '=' }, transclude: true, link: function(scope, element, attrs){ scope.account={}; console.log('SCOPE: ', scope) } }; }]); 

HTML:

 <form-control account='account'> <label for="name">Enter Name:</label> <input name="name" ng-model="account.name" \> </form-control> 

2) Using the transclude function:

This is similar to what ngIf and ngRepeat . ngRepeat actually decorates each area with $index and similar values, just like you want to decorate your area with account .

http://plnkr.co/edit/cZjWqIgO23nzc0kMZA57

JS:

 app.directive('formControl', ['$animate', function($animate){ return { restrict: 'EA', transclude: 'element', link: function(scope, element, attrs, ctrl, transclude){ //this creates a new scope that inherits from the parent scope //that new scope will be what you'll be working with inside your //transcluded html transclude(function (clone, scope) { scope.account = {name:'foobar'}; $animate.enter(clone, null, element); console.log('SCOPE: ', scope) }); } }; }]); 

HTML:

 <form-control> <label for="name">Enter Name:</label> <input name="name" ng-model="account.name" \><br> {{account.name}} </form-control> 
+1
source

Source: https://habr.com/ru/post/1234266/


All Articles