1

I have directive which dynamically creates input tags. I need to get values of created inputs on change event. Instead of it the name attribute on $scope argument in the controller is undefined. How to get ng-model value in the directive controller?

module.directive('createControl', function($compile, $timeout){
   return {           
     transclude: true,
     restrict: 'A',   
     scope: {         
       name: '=name'
     },
     link: function(scope, element, attrs){
         // simplified version
         tag = '<input type="text" ng-model="name"/>'
         element.append(html);
     controller: function($scope){
         // In the controller I need to get value of created input on change event
         console.log($scope);
     }
   }
});
1
  • could you share complete code with directive declaration in html .pls set up a plunker code or jsfiddle Commented May 9, 2013 at 6:41

2 Answers 2

2

I'm not 100% sure what you want to do, but I'm guessing it's something like this:

module.directive('createControl', function($compile, $timeout){
   return {   
     transclude: true,
     restrict: 'A',   
     scope: {         
       name: '=name'
     },
     link: function(scope, element, attrs){
         // simplified version
         var tag = angular.element('<input type="text" ng-model="name" ng-change="changed(name)">');
         element.append(tag);
         $compile(tag)(scope);
     },
     controller: function($scope){
         // In the controller I need to get value of created input on change event
         $scope.changed=function(name){
           console.log('changed to: '+name);
         }
     }
   }
});

The link function creates a new input element, compiles it with the $compile service and then links the new input element with scope. This works with the following markup:

Hello {{myInput}}!
<div create-control name="myInput">  
</div>

Check out this plunker: http://plnkr.co/edit/7XY90LXNn6gqpP47JaCH?p=preview

Sign up to request clarification or add additional context in comments.

Comments

1

The problem is controller executed earlier than directive. So in controller should be $watched $scope, not html tags added in a directive. However I think a controller binded to a directive should not know about directive state, correct me if I am wrong.

So there is two approaches:

module.directive('createControl', function($compile, $timeout){
   return {   
     transclude: true,
     restrict: 'A',   
     scope: {         
        name: '=name'
     },
     link: function($scope, $element, $attrs){
         // simplified version
         var tag = angular.element('<input type="text" ng-model="name" ng-change="changed(name)">');
         $element.append(tag);
         $compile(tag)(scope);
     },
     controller: function($scope, $element, $attrs){
         $scope.$watch('Name', function(){            
             console.log(arguments);                    
         });                                          
     }         
});                                     

The second one:

module.directive('createControl', function($compile, $timeout){
   return {   
     transclude: true,
     restrict: 'A',   
     scope: {         
        name: '=name'
     },
     link: function($scope, $element, $attrs){
         // simplified version
         var tag = angular.element('<input type="text" ng-model="name" ng-change="changed(name)">');
         $element.append(tag);
         $compile(tag)(scope);
         $element.find('input').on('change', function(){
             console.log($scope);
         })
     }
});

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.