在parent上执行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/

请注意,当您添加选项时,在父节点上退出的选项数组是未定义的。

开始工作了。所有的教程都是通过调用ng-click上的parent方法来实现的,基本上绕过了子控制器。但是,如果您需要在将值传递给父指令之前进行验证,则需要在子指令上调用方法,然后在该调用中调用父指令的方法。

可以访问它,就像将表达式放入ng-click一样。

下面是显示此工作的小提琴:http://jsfiddle.net/y4uzbapz/3/

注意ng-click处理程序实际上在子指令上,它调用父指令的方法。这让我可以对该数据进行一些预处理/后期处理,如果我直接从ng-click调用父指令,我就无法做到。

不管怎样,结案了:)

最新更新