質問

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);
     }
   }
});
役に立ちましたか?

解決

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

他のヒント

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);
         })
     }
});
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top