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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.