2014-12-04 39 views
0

我有兩個點擊操作的表格 - 第一個點擊負責打開反饋的整個行,第二個點擊將項目添加到團隊的名稱。防止控制器和指令在同一頁面上的默認設置

<div id="content_people" ng-show="active=='people'" ng-controller="DevsListCtrl"> 
    <table ng-table="tableParams" class="table"> 
     <tbody ng-repeat="d in $data" ng-controller="feedbackCtrl"> 
      <tr ng-click="onItemClick(d.name,$event)"> 
       <td add-new-team-member data-title='name' data-value="{{d}}">{{d.name}}</td> 
       <td data-title='age'>{{d.age}}</td> 
       <td data-title='grade'>{{d.grade}}</td> 
       <td data-title='job'>{{d.job}}</td> 
      </tr> 
      <tr ng-show="isOpen(d.name)" ng-repeat = "f in getFeedback(d.name)" > 
       <td colspan="4" width="100%"> 
        {{f}} 
       </td> 
      </tr> 
      <tr ng-show="isOpen(d.name)"> 
       <td colspan="4" width="100%" ng-form="feedbackForm"> 
        <input id="name" type="text" ng-model="comment" ng-minlength="10" required> 
        <input ng-click="submitNewFeedback(d.name, comment)" type="submit" value="Add new feedback" ng-disabled="feedbackForm.$invalid" > 
       <td> 
      </tr> 
     </tbody> 
    </table> 
</div> 

當前點擊整行打開反饋部分以及。我想避免這種情況,尋找解決方案,我們在指令情況類似:

mainApp.directive("addNewTeamMember", ['teamSharedObj', function (teamSharedObj) { 
    return { 
     restrict: 'A', 
     link: function(scope, element, attrs) { 
      element.bind('click', function(e) { 
       e.preventDefault(); 
       console.log(scope.teamMemberName) 
       scope.$apply(function() { 
        if (typeof teamSharedObj.selected == 'undefined') { 
         alert("No team. Please select team."); 
         return; 
        } 

        var result = []; 
        var asObject = JSON.parse(attrs.value); 
        result.push(asObject); 
        teamSharedObj.addTeamMembers(teamSharedObj.selected, result); 
       }); 
      }); 
//   element.on('click', function(e){ 
//    e.preventDefault(); 
//   }); 
     } 
    } 
}]) 

我嘗試不同的情況下,但沒有任何工程。最流行的建議是使用一個事件,以防止他人行動點擊:

$scope.clicked = function(what, event) { 
    alert(what + ' clicked'); 
    if(event){ 
     event.stopPropagation(); 
     event.preventDefault(); 
    } 
    } 

我的控制器:

mainApp.controller("feedbackCtrl", [ '$scope', 'teamSharedObj', function($scope, teamSharedObj) { 
    // control visibility state 
    $scope.state = 'off'; 
    $scope.selected = "undefined"; 
    $scope.isOpen = function(employee) { 
     return $scope.state === "on" && $scope.selected === employee; 
    } 
    // handle click on item 
    $scope.onItemClick = function(employee, event) { 
     event.stopPropagation(); 
     event.preventDefault(); 
     $scope.state = ($scope.state === 'on' ? 'off' : 'on'); 
     $scope.selected = employee; 
    } 
    // open appropriate feedback container 
    $scope.getFeedback = function(employee) { 
     var result = teamSharedObj.feedback[employee] ? teamSharedObj.feedback[employee] : "<div> No values </div>"; 
     return result ; 
    } 
    $scope.submitNewFeedback = function(employee, feedback) { 
     teamSharedObj.addFeedback(employee, feedback); 
    } 
}]); 

我發現指令點擊其內部行調用第一個也是唯一然後控制器點擊是擊中。我把preventDefault放在兩個問題上,但問題仍然是一樣的。在這種情況下你有什麼想法可以幫忙嗎?

回答

1

如果我理解正確你你想要的以下內容:

td的點擊與add-new-team-member屬性應該只火在指令中的單擊事件處理程序。

單擊該行其他任何位置應該觸發控制器中的onItemClick函數。

preventDefault不會幫助你,因爲它只會阻止瀏覽器在該事件中進行的默認操作。

你需要的是stopPropagation,它阻止事件冒泡事件鏈。

簡化你有什麼版本:

<tr controller-event-listener> 
    <td directive-event-listener> 
    </td> 
</tr> 

如果你點擊td,不希望事件冒泡到tr,你需要調用stopPropagation

在您的指令把這應該是足夠了:

element.on('click', function(e) { 
    e.stopPropagation(); 
+0

其實我不明白在這種情況下的最佳實踐。我收到了一個反饋並重寫了這段代碼,將所有這些操作放在一個控制器中,並在服務中提取一些功能。在此之後停止傳播工作正常。感謝您的幫助,upvote您的帖子 – 2014-12-05 08:59:05