有条件地将属性指令添加到 ng-repeat

Conditionally add attribute directive to the ng-repeat

我想知道是否可以将属性指令添加到 ng-repeat 中的某些元素。我试过检查 CSS class 或 id 但没有运气。

示例代码

class ItemNavigation {

  constructor(NavigationService ) {
      this.NavigationService = NavigationService;
  }

}

angular.module('core')
  .directive('itemNavigation', function ($timeout) {
    return {
      bindToController: true,
      scope: {
        itemId: '='
      },
      controllerAs: '$ctrl',
      restrict: 'A',
      link: function(scope, elem, attrs, ctrl) {
        $timeout(() =>{
          elem.bind('click', function() {
            let noRedirect = $(this).hasClass('no-redirect');
            // this approch doesnt work it never finds class
            if(!noRedirect) return ctrl.NavigationService.goToItemDetails(ctrl.itemId)        
          })
        })
       ;
      },
      controller: ItemNavigation 
    };
  });

html

的例子
    <tr ng-repeat="item in $data track by item.id" item-navigation item-id="item.id">
      <td class="no-redirect">I dont want my directive to work here</td>
      <td>I want my directive to work here</td>
      <td>I want my directive to work here</td>
      <td class="no-redirect">I dont want my directive to work here</td>
      <td>I want my directive to work here</td>
      <td>I want my directive to work here</td>
    </tr>

如有任何帮助,我将不胜感激

我认为你可以;据我了解,您只想为偶数行设置条件。

一个简单的解决方案:在 ng-repeat 行中放置一个使用 $index 的条件。

  <tr ng-repeat="item in $data track by item.id" item-navigation item-id="item.id">
  <td class="no-redirect" ng-if="$index % 3 == 0">I dont want my directive to work here</td>
  <td class="no-redirect" ng-if="$index % 2 == 0">I want my directive to work here</td>

</tr>

这些是您需要在指令中进行的更改。

   app.directive('rowNavigation', function ($timeout) {
    return {
      scope: {
    itemId: '='
  },
  controllerAs: 'ctrl',
  restrict: 'A',
  link: function(scope, elem, attrs, ctrl) {
      $timeout(function() {
      elem.bind('click', function() {
         console.log(ctrl)
         alert(ctrl.itemId);
      })
   });
  },
  controller: function($scope) {
    this.itemId = $scope.itemId
   } 
};
});

然后在你的 ng-repeat 中,将其更改为

 <tr ng-repeat="one in data"  item-id="one.id"
  class="table table-striped table-bordered">
    <td  class="no-redirect">Dont alert when i click here</td>
    <td row-navigation item-id="one.id">Alert when i click here</td>
    <td row-navigation item-id="one.id">Alert when i click here</td>
  </tr>

希望对您有所帮助。

在检查 hasClass 而不是 element 本身时,您似乎将其绑定到 window 对象。

let noRedirect = $(this).hasClass('no-redirect'); // update this
let noRedirect = elem.hasClass('no-redirect'); // this should help

可以console.log验证一下吗? 让我们知道。

如果目标是更改子节点上的点击行为,只需使用 ng-click 指令:

<table>
<!--       Also please dont use stop Event.stopPropagation() 
           as it breaks some of flow on mobile devices in my application 
-->
  <tr ng-repeat="one in data" ng-click="alert(one.id)"
  class="table table-striped table-bordered">
    <td class="no-redirect" ng-click="dontAlert($event)">
        Dont alert when i click here</td>
    <td>Alert when i click here</td>
    <td>Alert when i click here</td>
  </tr>
</table>

为了避免使用 event.stopPropagation,让子点击处理程序为父点击处理程序设置一个标志:

var dontAlertFlag = false;

$scope.alert = function(id) {
    !dontAlertFlag && alert(id);
    dontAlertFlag = false;
};
$scope.dontAlert = function(event) {
    //event.stopPropagation();
    dontAlertFlag = true;
    console.log(event);
} 

在上面的示例中,当单击子元素时,子单击处理程序将 dontAlertFlag 设置为 true。父点击处理程序使用该标志然后将其重置。

DEMO on PLNKR


更新

可以使用 event.target 属性:

来简化代码
<table>
<!--       Also please dont use stop Event.stopPropagation() 
           as it breaks some of flow on mobile devices in my application 
-->
  <tr ng-repeat="one in data" ng-click="alert(one.id,$event)"
  class="table table-striped table-bordered">
    <td class="no-redirect">
        Dont alert when i click here</td>
    <td>Alert when i click here</td>
    <td>Alert when i click here</td>
  </tr>
</table>

JS

   $scope.alert = function(id,event) {
        var $target = angular.element(event.target);
        console.log($target);
        if (!$target.hasClass("no-redirect")) {
             alert(id);
        }
        console.log(event);
    };

在上面的示例中,点击处理程序检查目标以查看它是否具有名为 no-redirect 的 class。如果目标没有 class,它会触发警报。

DEMO on PLNKR

您可以将事件目标添加到您的代码中,如果您需要从 tds 复制文本并且您的指令仅在您单击文本外部时才会起作用,它也将解决问题。您也可以从代码中删除超时。

请检查以下更改

   <table>
      <tr ng-repeat="one in data" row-navigation item-id="one.id"
      class="table table-striped table-bordered">
        <td class="no-redirect">Dont alert when i click here</td>
        <td><span class="no-redirect">Dont when i click on this text only, but works in TD element</span></td>
        <td>Alert when i click here</td>
      </tr>
    </table>

您的链接函数应该如下所示

 app.directive('rowNavigation', function () {
    return {
      scope: {
        itemId: '='
      },
      controllerAs: 'ctrl',
      restrict: 'A',
      link: function(scope, elem, attrs, ctrl) {

          elem.bind('click', function(event) {
            var noRedirect = $(event.target).hasClass('no-redirect');
            // it will work now
            if(!noRedirect) alert(ctrl.itemId)        
          })

      },
      controller: function($scope) {
        this.itemId = $scope.itemId
       } 
    };
  });