Как удалить ограничение фильтра limitTo для события наведения мыши? - PullRequest
0 голосов
/ 29 августа 2018

У меня есть массив объектов с именем articles, каждый из которых содержит массив строк с именем category. Каждая статья представлена ​​в DOM директивой ngRepeat, которая содержит вторую директиву ngRepeat для представления каждой категории. Второй ngRepeat имеет фильтр limitTo, который ограничивает число категорий до 2. Когда пользователь наводит курсор на базовый элемент article, ограничение должно быть удалено, и все строки в массиве category должны быть видны.

Моя проблема в том, что когда пользователь наводит мышью на один элемент, раскрывается полный массив категорий для каждого объекта в массиве articles. Как я могу заставить DOM раскрывать только полные категории для элемента, на котором происходит событие мыши?

Plunkr: https://plnkr.co/edit/PW51BBnQEv589rIdnaCK?p=preview

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

Вот еще один способ, к которому можно приблизиться. Я удалил директиву ng-if, так как она не нужна. В вашей первой директиве ng-repeat объект article доступен в используемой области. $scope.hoverMode был удален в пользу добавления attr к каждой статье под названием limit.

Событие ng-mouseover, которое я заменил в пользу ng-mouseenter, так как это событие, параллельное ng-mouseleave. Вместо того, чтобы эти директивы вызывали функцию, предельным значением манипулируют с помощью простого выражения в DOM. Я оставил функцию showAllCat() в коде с изменениями. Он принимает объект статьи в качестве параметра для непосредственного управления категорией.

Если limit var равен undefined, то в фильтре нет ограничения по пределу.

Удаляя ng-if, вы удаляете количество слушателей, равное количеству статей. Так как в этом не было необходимости, это просто дополнительные накладные расходы.

// Code goes here

angular
  .module('myApp', [])
  .controller('myController', ($scope) => {
    $scope.minLimit = 2;
    $scope.maxLimit = undefined;

    $scope.articles = [{
      date: 'some',
      category: [{
        name: "Sports"
      }, {
        name: "News"
      }, {
        name: "Cinema"
      }]
    }, {
      date: 'some',
      category: [{
        name: "A"
      }, {
        name: "B"
      }, {
        name: "C"
      }]
    }, {
      date: 'some',
      category: [{
        name: "D"
      }, {
        name: "E"
      }, {
        name: "F"
      }]
    }];
    $scope.articles.forEach((article)=>{article.limit=$scope.minLimit});
    
    $scope.showAllcat = function(article) {
      console.log('hover working');
      article.limit = article.limit === minLimit ? maxLimit : minLimit;
    }
  });
<!DOCTYPE html>
<html ng-app='myApp'>

<head>
  <script data-require="angular.js@4.0.0" data-semver="4.0.0" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.10/angular.min.js"></script>
  <script data-require="angular.js@4.0.0" data-semver="4.0.0" src="script.ts"></script>
  <script data-require="angular.js@4.0.0" data-semver="4.0.0" src="system.config.js"></script>
  <script data-require="angular.js@4.0.0" data-semver="4.0.0" src="tsconfig.json"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body ng-controller='myController'>
  <table>
    <tbody>
      <tr>
        <th>Date</th>
        <th>Categories</th>
      </tr>
      <tr ng-repeat="article in articles"
          ng-mouseenter="article.limit = maxLimit"
          ng-mouseleave="article.limit = minLimit">
        <td><span>{{ article.date }}</span></td>
        <td><span ng-repeat="cat in article.category | limitTo: article.limit">&nbsp;
                <span class="label label-warning">{{cat.name}}
                </span>
            </span>
        </td>
      </tr>


    </tbody>
  </table>
</body>

</html>
0 голосов
/ 29 августа 2018

Вы можете передать свою статью, на которую вы наводите курсор, и установить ее в переменной scope. Чем просто обновить ваш ng-if чек на:

ng-if="hoverMode === true && hoveredArticle === article"

Рабочий пример:

// Code goes here

angular
 .module('myApp', [])
 .controller('myController', ($scope) => {
   
   $scope.articles = [ { date: 'some', category: [ {name: "Sports"}, {name: "News"}, {name: "Cinema"} ] }, { date: 'some', category: [ {name: "A"}, {name: "B"}, {name: "C"} ] }, { date: 'some', category: [ {name: "D"}, {name: "E"}, {name: "F"} ] } ]
 
  $scope.hoverMode = false;

  $scope.showAllcat = function(article) {
   $scope.hoveredArticle = article;
   $scope.hoverMode = true;
  }
	 
  $scope.hideAllcat = function() {
   $scope.hoveredArticle = null;
   console.log('hover working');
   $scope.hoverMode = false;
  }
 
 
 
 });
<!DOCTYPE html>
<html ng-app='myApp'>

<head>
  <script data-require="angular.js@4.0.0" data-semver="4.0.0" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.10/angular.min.js"></script>
  <script data-require="angular.js@4.0.0" data-semver="4.0.0" src="script.ts"></script>
  <script data-require="angular.js@4.0.0" data-semver="4.0.0" src="system.config.js"></script>
  <script data-require="angular.js@4.0.0" data-semver="4.0.0" src="tsconfig.json"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body ng-controller='myController'>
  <table>
    <tbody>
      <tr>
        <th>Date</th>
        <th>Categories</th>
      </tr>
      <tr ng-repeat="article in articles">
        <td><span>{{ article.date }}</span></td>
        <td ng-if="hoverMode === false || hoveredArticle !== article">
            <span ng-repeat="cat in article.category | limitTo: 2">&nbsp;
                <span class="label label-warning"
                      ng-mouseover="showAllcat(article)">{{ cat.name}}
                </span>
            </span>
        </td>
        <td ng-if="hoverMode === true && hoveredArticle === article">
            <span ng-repeat="cat in article.category">&nbsp;
                <span class="label label-warning"
                      ng-mouseleave="hideAllcat()">{{ cat.name}}
                </span>
            </span>
        </td>
      </tr>


    </tbody>
  </table>
</body>

</html>
...