Удаление класса из всех дочерних элементов, кроме щелкнутого дочернего элемента при ng-click в Angular

У меня есть простой элемент списка, который анализируется с помощью ng-repeat:

<ul>
    <li ng-repeat="item in items" class="commonClass" ng-class="{'on': on_var}" ng-click="on_var=!on_var"> 
   {{item.name}} 
    <li>
</ul>

щелчок по элементу списка добавит имя класса «on», как и ожидалось. но я хочу удалить все остальные классы «включено», как только вы нажмете на другой элемент списка, и добавить его только к тому, на который нажали. Я родом из фона jQuery, и я новичок в angular. Все, что я хочу сделать, это что-то вроде этого:

$("li.commanClass").click(function(){ 
    $("li.commonClass").removeClass('on');
    $(this).addClass('on');
})

Я хочу знать, что такое «угловой способ» достижения этого результата.

jsfiddle

Спасибо.


person Sammy    schedule 07.07.2014    source источник


Ответы (4)


В angular вы хотите как можно больше передавать ссылки на объекты дочерним областям. Таким образом, вы можете использовать прототипное наследование объектов, которое может разветвляться на многие уровни.

Думайте о области как о model. В случае ng-repeat создается дочерняя область для каждого элемента. Поэтому, если родительская область содержит модель, она будет передана в качестве ссылки на дочерние области. Каждая из этих дочерних областей будет содержать ссылку на объект модели родительской области.

Таким образом, вы можете сделать:

<li ng-repeat="item in model.items" 
    ng-class="{'on': model.selected==item}" 
    ng-click="model.selected=item">{{ item.name }}</li> 

Затем в контроллере:

$scope.model = {
        selected: null,
        items = [
            {name: "Apple"}, 
            {name: "Banana"}, 
            {name: "California"}
         ]
    };

Старайтесь избегать использования функций, как это делает ответ выше. Эти функции будут вызываться много раз и добавят ненужные дополнительные накладные расходы.

Полезный пост для чтения: Думаете на AngularJS, если у меня есть опыт работы с jQuery?

ДЕМО

person charlietfl    schedule 08.07.2014
comment
Спасибо! Кажется, что все предоставленные ответы работают, но этот мне нравится больше всего. - person Sammy; 08.07.2014

Вы можете добавить переменную в свою область, чтобы сохранить, какой элемент выбран, и функцию в вашей области, которая переключает переменную.

Контроллер:

app.controller('myCtrl', function($scope) {
    $scope.items = 
    [
        {name: "Apple"},
        {name: "Banana"},
        {name: "California"}
    ]

    $scope.selectItem = function( item ) {
        $scope.selectedItem = item;
    };
})

HTML:

<div ng-app="myApp">
    <ul ng-controller="myCtrl">
        <li ng-repeat="item in items" class="commonClass" ng-class="{'on': selectedItem === item}" ng-click="selectItem(item)">
            {{ item.name }}
        </li>
    </ul>
</div>
person jsparks    schedule 08.07.2014

Скрипка приходит на ответ jsparks:

http://jsfiddle.net/eHDTF/

See fiddle for code!
person chubbsondubs    schedule 08.07.2014

Я думаю, вам следует указать директиву для всего вашего проекта вместо контроллера.

<div class="nav-item">
    <ul>
        <li active-me="on">Item 1</li>
        <li active-me="on">Item 2</li>
        <li active-me="on">Item 3</li>
        <li active-me="on">Item 4</li>
        <li active-me="on">Item 5</li>
    </ul>
</div>

Затем создайте директиву activeMe:

angular.module('app').directive('activeMe', function(){
    return {
        restrict: 'A',
        scope: {
            activeMe: '@'
        },
        link: function(scope, element, attrs) {
            element.bind('click', function() {
                if (scope.activeMe !== undefined && scope.activeMe.trim().length > 0) {
                    element.parent().children().removeClass(scope.activeMe);
                    element.addClass(scope.activeMe);
                } else {
                    element.parent().children().removeClass('active');
                    element.addClass('active');
                }
            });
        }
    };
});
person Hieu Tran AGI    schedule 09.05.2017