2016-11-17 50 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調用父指令,則無法做到這一點。

無論如何,情況下關閉:)