Angular ng-если какой-либо дочерний элемент содержит

#javascript #angularjs #angular-ng-if

#javascript #angularjs #angular-ng-if

Вопрос:

Я пытаюсь условно отображать и скрывать столбцы на основе возвращаемых данных, если набор данных содержит какие-либо объекты, удовлетворяющие условиям.

Вот пример данных, возвращенных из моих результатов поиска

 [
    {
        "id": "typeahead-241-1091-option-0",
        "label": "Android Home Page",
        "model": {
            "type": "link",
        }
    },
    {
        "id": "typeahead-241-1091-option-1",
        "label": "Google",
        "model": {
            "type": "link",

        }
    },
    {
        "id": "typeahead-241-1091-option-2",
        "label": "Forgotten Google Play Password",
        "model": {
            "type": "kb",

        }
    }
]
 

Теперь я представляю данные в столбцах, в зависимости от типа.

 <div class="flexitem">
  <h4>External Links</h4>
  <div ng-repeat="match in matches" ng-if="match.model.type == 'link'">{{match.label}}</div>
</div>
<div class="flexitem">
  <h4>Knowledge Base</h4>
  <div ng-repeat="match in matches" ng-if="match.model.type == 'kb'">{{match.label}}</div>
</div>
<!-- the below has no results. I want it hidden altogether
currently it shows the <h4>Products</h4> with nothing below it-->
<div class="flexitem">
  <h4>Products</h4>
  <div ng-repeat="match in matches" ng-if="match.model.type == 'product'">{{match.label}}</div>
</div>
 

Что мне нужно сделать, так это полностью установить условия для гибких элементов div, чтобы показывать только, есть ли результаты для этого типа. Так что, если нет результатов с типом == ‘product’, то даже не показывайте этот div. Ng-if в этой строке будет работать, но каков будет наилучший способ перебора всех дочерних элементов match, чтобы определить, есть ли результат? indexOf не работает через дочерние массивы.

Комментарии:

1. Возможно, я был неясен. Я пытаюсь полностью скрыть <div class=»flexitem» . Div с ng-repeat работает правильно. Я отредактирую, чтобы показать это более четко

Ответ №1:

Поместите логику на угловую сторону, используя Array.filter для разделения массивов;

Угловой контроллер:

 $scope.linkMathches = $scope.matches.filter(function(m){
  return m.model.type === 'link'
});
$scope.kbMathches = $scope.matches.filter(function(m){
  return m.model.type === 'kb'
});
 

HTML:

 <div class="flexitem" ng-if="linkMathches.length">
  <h4>External Links</h4>
  <div ng-repeat="match in linkMathches">
    {{match.label}}
  </div>
</div>
<div class="flexitem" ng-if="kbMathches.length">
  <h4>Knowledge Base</h4>
  <div ng-repeat="match in kbMathches">
    {{match.label}}
  </div>
</div>
 

Идем дальше для динамических значений в model.type :

Угловой контроллер:

 $scope.typeMatches = {
  link: {title: 'External Links', matches: []},
  kb: {title: 'Knowledge Base', matches: []},
  product: {title: 'Products', matches: []}
};

$scope.matches.forEach(function(match){
  $scope.typeMatches[match.model.type].matches.push(match);
});
 

HTML:

 <div class="flexitem"
    ng-if="value.matches.length"
    ng-repeat="(key,value) in typeMatches">
  <h4>{{value.title}}</h4>
  <div ng-repeat="match in value.matches">
    {{match.label}}
  </div>
</div>
 

Комментарии:

1. Это может сработать. Однако у меня возникла проблема с доступом к данным, поскольку они вызываются из поиска по типу. В понедельник мне нужно будет провести некоторую переоценку.