有条件地将属性指令添加到 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
。父点击处理程序使用该标志然后将其重置。
更新
可以使用 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,它会触发警报。
您可以将事件目标添加到您的代码中,如果您需要从 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
}
};
});
我想知道是否可以将属性指令添加到 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
。父点击处理程序使用该标志然后将其重置。
更新
可以使用 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,它会触发警报。
您可以将事件目标添加到您的代码中,如果您需要从 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
}
};
});