2016-11-17 52 views
0

我在指令中有一个指令,需要使用child指令调用父指令。我在传递数据方面遇到了一些麻烦,并认为你们都可能有一个想法。在父母上执行Angular指令方法时遇到问题

这里的设置:

我父指令被称为screener-item。我的孩子指令称为option-item。在每个screener-item的内部,可能有n option-item s,因此它们是动态添加的。 (本质上,认为这是动态生成一个下拉的:用户给它一个标题,然后提供一组选项)

下面是这是怎么设置:

screener-item.directive.js

angular.module('recruitingApp')                        
    .directive('screenerItem', function(Study, $compile) {                 
    return {                            
     templateUrl: 'app/new-study/screener-item/screener-item.html',              
     scope: {                           
     study: '='                          
     },                             
     link: function(scope, el, attrs) {                     
     var options = []; 

     scope.addOptionItem = function(item) {                   
      options.push(item);                                        
     }  

     scope.saveScreenerItem = function() {                   
      if (scope.item._id) {                       
      var isEdit = true;                       
      }                            
      Study.addScreenerQuestion({id:scope.study._id},{                
      _id: scope.item._id,                       
      text: scope.item.text,                      
      type: scope.item.type                      
      }, function(item){                        
      scope.mode = 'show';                       
      scope.item._id = item._id;                     
      if (!isEdit) {                        
       el.parent().append($compile('<screener-item study="newStudy.study"></screener-item')(scope.$parent));  
      }                           
      });                           
     }                            
     }                             
    }                             
    }); 

screener-item.html

<div class="screener-item row" ng-hide="mode == 'show'">                 
    <div class="col-md-8">                         
    <input type="text" placeholder="Field (e.g., name, email)" ng-model="item.text">          
    </div>                             
    <div class="col-md-3">                         
     <select ng-model="item.type">                      
     <option value="text">Text</option>                     
     <option value="single_choice">Single Select</option>                
     <option value="multi_choice">Multi Select</option>                 
     </select>                           
     <div ng-show="item.type == 'single_choice' || fieldType == 'multi_choice'">           
     <h6>Possible answers:</h6>                       
     <option-item item-options="options" add-option-item="addOptionItem(value)"><option-item>       
     </div>                            
    </div>                             
    <div class="col-md-1">                         
     <button ng-click="saveScreenerItem()">Save</button>                 
    </div>                             
    </div>                             
    <div class="screener-item-show row" ng-model="item" ng-show="mode == 'show'">           
    <div class="col-md-8">{{item.text}}</div>                    
    <div class="col-md-3">({{item.type}})</div>                   
    <div class="col-md-1">                         
     <a ng-click="mode = 'add'">edit</a>                     
    </div>                             
    </div> 

你会注意到option-item它包含在它们中间。这是提供给用户的最初选项。这可能会重复,因为用户需要它。

option.item.directive.js

angular.module('recruitingApp')                        
    .directive('optionItem', function($compile) {                    
    return {                            
     templateUrl: 'app/new-study/screener-item/option-item.html',               
     scope: {                            
     addOptionItem: '&'                         
     },                             
     link: function(scope, el, attrs) {                     
     scope.mode = 'add';                         
     scope.addItem = function(value) {                     
      console.log("Value is ", value);                     
      scope.addOptionItem({item:value});                    
      scope.mode = 'show';                        
      var newOptionItem = $compile('<option-item add-option-item="addOptionItem"></option-item')(scope);    
      el.parent().append(newOptionItem);                    
     }                             
     }                              
    }                              
    }); 

option-item.html

<div ng-show="mode == 'add'">                       
    <input type="text" ng-model="value">                     
    <button ng-click="addItem(value)">Save</button>                  
</div>  

这是我希望发生的:当用户输入的option-item文本框的值,并保存它,我想在调用addItem(),方法option-item指令。然后,该方法将调用父方法 - addOptionItem(),传递该值,该值将被推送到保存在父级上的数组中(该数组跟踪添加的所有选项)。

我可以得到它来执行父方法,但对于我的生活,我无法让它通过值 - 它出现为undefined每次。

我试图调用option-item方法而不是直接转到父项,这样我可以根据需要进行验证,因此一旦添加项目,我就可以在当前项下动态添加另一个option-item

我希望这是有道理的,请让我知道,如果这是可怕的不清楚。

谢谢!

编辑:这里是它的一个的jsfiddle:http://jsfiddle.net/y4uzbapz/1/

需要注意的是,当你添加选项,选项父被注销阵列是不确定的。

+0

你能用你的代码创建JSFiddle吗? – tomepejo

+0

是的,给我一点,尽可能准确地重建它。 –

+0

@TomePejoski小提琴在这里创建:http://jsfiddle.net/y4uzbapz/1/ –

回答

0

得到了这个工作。所有教程通过调用ng-click上的父方法来实现此功能,实质上绕过了子控制器。但是,如果需要在将值传递给父代之前进行验证,则需要调用子指令的方法,然后在该调用中调用父指令的方法。

原来,您可以像访问ng-click中的表达式一样访问它。

这里是显示这个工作小提琴:http://jsfiddle.net/y4uzbapz/3/

注意,ng-click处理实际上是对孩子的指令,它调用父指令的方法。这让我可以对这些数据做一些预处理/后处理,如果我直接从ng-click调用父指令,则无法做到这一点。

无论如何,情况下关闭:)