Привязать нг-клик к классу CSS

Можем ли мы связать ng-click с классом CSS?

У меня куча <td> s, чтобы связать и проверить, нажаты ли они, затем выстрелить щелчком метки в нем, чтобы дать максимально активируемую область для сенсорных устройств.

Я сделал что-то вроде ниже.

var myApp = angular.module("myApp", [])
  .controller("myController", ["$scope", "$timeout", function myController($scope, $timeout) {
    $scope.checkRadio = function checkRadio($event) {      
      $timeout(function() {
        angular.element($event.target).find("label").trigger('click');
      }, 100);
    };
  }]);
.invisible-radio {
  position: absolute;
  display: inline;
  opacity: 0;
  width: 0;
  margin: 0;
  -webkit-appearance: none;
  overflow: hidden;
}

.custom-radio-label {
  display: inline-block;
  position: relative;
  padding-left: 20px;
  vertical-align: text-top;
  line-height: 20px;
  cursor: pointer;
  border-style: solid;
  border-width: 0;
}

.custom-radio-label::before {
  border-color: #7f7f7f;
  border-radius: 50%;
  background-color: #fff;
  border-width: 2px;
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 18px;
  height: 18px;
  border-style: solid;
  -webkit-box-sizing: content-box;
  -moz-box-sizing: content-box;
  box-sizing: content-box;
}

.invisible-radio:checked+.custom-radio-label::after {
  background-color: #337ab7;
  border-radius: 50%;
  top: 5px;
  left: 5px;
  content: "";
  width: 12px;
  height: 12px;
  position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<table class="table table-hover text-center center-block" ng-app="myApp" ng-controller="myController">
  <thead>
    <tr>
      <th>Option 1</th>
      <th>Option 2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td ng-click="checkRadio($event)">
        <input id="option1" type="radio" class="invisible-radio" name="option" value="0" ng-model="model.Option" required />
        <label class="custom-radio-label" for="option1"></label>
      </td>
      <td ng-click="checkRadio($event)">
        <input id="option2" type="radio" class="invisible-radio" name="option" value="1" ng-model="model.Option" required />
        <label class="custom-radio-label" for="option2"></label>
      </td>
    </tr>
  </tbody>
</table>

Но это кажется излишним, чтобы пойти и украсить сотни <td> с ng-click приписывать.

Я думаю, можно ли связать ng-click в общий класс, что все мои <td> поделиться.

Это, безусловно, возможно сделать с jQuery как ниже.

$(".someclassOnMyTD").click($event) {
   $event.target.find("label").click();
}

Но я ищу здесь угловой путь. Директива возможно.

3 ответа

Решение

Вы можете сделать это с помощью angular.element

  var cells = angular.element(document.querySelectorAll(".someclassOnMyTD"));
  cells.on('click', function(event){
        // write your code here
        // var labels = angular.element(event.currentTarget).find('label');
  })

На самом деле это то, что <label> за.

<td>
  <label for="option1">
    <input id="option1" type="radio" class="invisible-radio" name="option" value="0" ng-model="model.Option" required />
    <label class="custom-radio-label" for="option1"></label>
  </label>
</td>

Возможно, вам придется немного поработать с CSS, чтобы он заполнил область своего родителя. td

Я использовал ng-view и нужно было связать событие со многими tdс почти во всех моих (более 20) просмотров.

Вот полное решение, так как оно может оказаться полезным для кого-то с таким же требованием, как у меня, в будущем.

$scope.$on('$viewContentLoaded', function () {
    var tables = angular.element(document.querySelectorAll(".myClassOnTable, .myOtherClassOnTable"));
    angular.forEach(tables, function (table) {
        angular.element(table).on("click", function (e) {
            var targetElement = e.target;
            if (targetElement.nodeName == "TD" || targetElement.nodeName == "td") {
                var radio = angular.element(targetElement).find(".invisible-radio");
                if (radio) {
                    angular.element(radio[0]).prop("checked", true);
                    // I needed to set the required attribute manually as I am setting the checked property manually
                    $scope.myForm[radio[0].name].$setValidity("required", true);
                    $scope.$apply();
                }
            }
        });
    });
});

Обратите внимание, что я связал событие click с table элемент, и я слушаю, если цель щелчка является td, Это связано с тем, что я столкнулся с приведенной ниже ошибкой из-за ограничения браузера, связывающего события кликов с сотнями элементов одновременно.

Uncaught RangeError: превышен максимальный размер стека вызовов

Поэтому я делегирую событие click меньшему количеству элементов.

Другие вопросы по тегам