0

РЕЗЮМЕ
У меня есть список брендов и список продуктов. Я использую ng-repeat, чтобы показать список брендов, и ng-repeat с фильтром, чтобы показать список продуктов в их соответствующих брендах. Я хочу, чтобы каждая марка и каждый продукт имели кнопку, которая больше описывает этот бренд/продукт. Все эти кнопки должны использовать ту же функцию на контроллере.Angular - могу ли я использовать одну функцию для нескольких объектов внутри вложенного ng-repeat, который запускает ng-show только этого объекта?

ПРОБЛЕМА
Кнопкой, которая показывает больше о марке также показывает больше о каждом из продуктов этой марки, КРОМЕ (это не странная часть для меня) я нажимаю кнопку продукта в этой марке первым, в в этом случае он будет работать правильно.

КОД
Пожалуйста, смотрите Plunker здесь, и обратите внимание, что при нажатии на «шоу типа» на бренд, это также показывает все виды продукции в рамках этого бренда: http://plnkr.co/edit/gFnq3O3f0YYmBAB6dcwe?p=preview

HTML

<!DOCTYPE html> 
<html> 

    <head> 
    <link rel="stylesheet" href="style.css"> 
    <script src="script.js"></script> 
    </head> 

    <body> 
    <div ng-app="myApp"> 
     <div ng-controller="MyController as vm"> 
     <div ng-repeat="brand in brands"> 
      <h1> 
       {{brand.name}} 
      </h1> 
      <button ng-click="showType(brand)"> 
      Show Brand Type 
      </button> 
      <div ng-show="show"> 
      {{brand.type}} 
      </div> 
      <div ng-repeat="product in products 
      | filter:filterProducts(brand.name)"> 
      <h2> 
        {{product.name}} 
       </h2> 
      <button ng-click="showType(product)"> 
       Show Product Type 
      </button> 
      <div ng-show="show"> 
       {{product.type}} 
      </div> 
      </div> 
     </div> 
     </div> 
    </div> 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script> 
    <script src="script.js"></script> 
    </body> 
</html> 

JAVASCRIPT

var app = angular.module('myApp', []); 

app.controller('MyController', function($scope) { 

    $scope.brands = [{ 
    name: 'Kewl', 
    type: 'Cereal' 
    }, { 
    name: 'Joku', 
    type: 'Toy' 
    }, { 
    name: 'Loko', 
    type: 'Couch' 
    }] 

    $scope.products = [{ 
    name: 'Kewlio', 
    type: 'Sugar Cereal', 
    brand: 'Kewl' 
    }, { 
    name: 'Kewliano', 
    type: 'Healthy Cereal', 
    brand: 'Kewl' 
    }, { 
    name: 'Jokurino', 
    type: 'Rattle', 
    brand: 'Joku' 
    }, { 
    name: 'Lokonoko', 
    type: 'Recliner', 
    brand: 'Loko' 
    }, { 
    name: 'Lokoboko', 
    type: 'Love Seat', 
    brand: 'Loko' 
    }] 

    $scope.showType = function(item) { 
    this.show = !this.show; 
    } 

    $scope.filterProducts = function(brand) { 
    return function(value) { 
     if(brand) { 
     return value.brand === brand; 
     } else { 
     return true; 
     } 
    } 
    } 
}); 

ВАЖНО ПРИМЕЧАНИЕ: Я понимаю, что могу добавить атрибут объекта (brand.show) и передать объект в функцию, а затем изменить этот атрибут на true/false, но я не хочу этого делать, потому что в моем действительном приложении кнопка отобразит форму, которая редактирует бренд/продукт и отправляет информацию в Firebase, и я не хочу, чтобы у объекта был атрибут show. Я бы предпочел не удалять атрибут 'show' каждый раз, когда я хочу редактировать информацию в Firebase.

ответ

0

ng-repeat директивы создать собственную сферу, когда вы делаете

this.show = !this.show 

создать/изменить show свойство в токе области применения, если нажмите бренд кнопка - для охвата бренда, что глобальное для продукта, и когда нажмите товар кнопка - для прицела конкретный товар.

Чтобы избежать этого, вы должны создать это свойство перед кнопкой, нажав, например, с ng-init, как

ng-init="show=false;" 

на элементе с `директивы нг-повтора»

Образец

var app = angular.module('myApp', []); 
 

 
app.controller('MyController', function($scope) { 
 

 
    $scope.brands = [{ 
 
    name: 'Kewl', 
 
    type: 'Cereal' 
 
    }, { 
 
    name: 'Joku', 
 
    type: 'Toy' 
 
    }, { 
 
    name: 'Loko', 
 
    type: 'Couch' 
 
    }] 
 

 
    $scope.products = [{ 
 
    name: 'Kewlio', 
 
    type: 'Sugar Cereal', 
 
    brand: 'Kewl' 
 
    }, { 
 
    name: 'Kewliano', 
 
    type: 'Healthy Cereal', 
 
    brand: 'Kewl' 
 
    }, { 
 
    name: 'Jokurino', 
 
    type: 'Rattle', 
 
    brand: 'Joku' 
 
    }, { 
 
    name: 'Lokonoko', 
 
    type: 'Recliner', 
 
    brand: 'Loko' 
 
    }, { 
 
    name: 'Lokoboko', 
 
    type: 'Love Seat', 
 
    brand: 'Loko' 
 
    }] 
 

 
    $scope.showType = function(item) { 
 
    this.show = !this.show; 
 
    } 
 

 
    $scope.filterProducts = function(brand) { 
 
    return function(value) { 
 
     if (brand) { 
 
     return value.brand === brand; 
 
     } else { 
 
     return true; 
 
     } 
 
    } 
 
    } 
 

 
});
/* Styles go here */ 
 

 
h1 { 
 
    font-family: impact; 
 
} 
 
h2 { 
 
    font-family: arial; 
 
    color: blue; 
 
    margin-bottom: 0; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script> 
 
<div ng-app="myApp"> 
 
    <div ng-controller="MyController as vm"> 
 
    <div ng-repeat="brand in brands" ng-init="show=false"> 
 
     <h1> 
 
       {{brand.name}} 
 
      </h1> 
 
     <button ng-click="showType(brand)"> 
 
     Show Brand Type 
 
     </button> 
 
     <div ng-show="show"> 
 
     {{brand.type}} 
 
     </div> 
 
     <div ng-repeat="product in products 
 
      | filter:filterProducts(brand.name)" ng-init="show=false"> 
 
     <h2> 
 
      {{product.name}} 
 
     </h2> 
 
     <button ng-click="showType(product)"> 
 
      Show Product Type 
 
     </button> 
 
     <div ng-show="show"> 
 
      {{product.type}} 
 
     </div> 
 
     </div> 
 
    </div> 
 
    </div> 
 
</div>

0

Ваш show boolean атрибут одинаковый для всего дерева (в той же области). Использование угловой директивы с охватом ребенка scope:true в ng-repeat помогает изолировать каждое свойство show. Я раздвоенный код plunker:

http://plnkr.co/edit/cMSvyfeCQOnTKG8F4l55?p=preview

+0

's cope: true' - не изолированная область видимости, является областью _child_, а также 'ng-repeat' уже создает собственную область – Grundy

+0

@Grundy true, спасибо за комментарий –

0

Самое простое решение для этого, если вы не против сдачи временных свойств в ваших данных является следующие изменения:

<div ng-show="product.show"> 
    {{product.type}} 
</div> 

и

<div ng-show="brand.show"> 
    {{brand.type}} 
</div> 

, а затем в вашем контроллере

$scope.showType = function(item) { 
    item.show = !item.show; 
    } 

В качестве альтернативы, если вы не хотите прикасаться к свойствам объекта, вы можете создать массив $ scope.shownTypes и щелкнуть или вставить объект в объект или удалить его из показанного массива. THEN вы можете проверить существование объекта в массиве и показать или не показывать тип соответствующим образом. Дайте мне знать, если вам нужен образец этого.

+0

Связано с вашим обновлением, см. раздел« Альтернативно »моего ответа – Beartums

Смежные вопросы