最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - ng-repeat: showing an item on click and hiding the others - Stack Overflow

programmeradmin3浏览0评论

I have a ng-repeat which display a list of divs and when I click on one it shows an aditionnal div for the clicked item.

This is working

<div ng-repeat="item in items">

    <div ng-click="showfull = !showfull">
        <div>
            <h1>{{item.title}}</h1>
            <p>{{item.content}}</p>
        </div>
    </div>
    <div ng-show="showfull">
        <p>{{item.info}}</p>
    </div>
    <hr/>
</div>

My items are loaded from a json containing a list of item and each item have a default attribut showfull set to false in this json. This is working, but now I want to hide all others item in the list when an item is clicked. I've tryied something like this :

This is not working

<div ng-repeat="item in items">

    <div ng-click="expand(item)">
        <div>
            <h1>{{item.title}}</h1>
            <p>{{item.content}}</p>
        </div>
    </div>
    <div ng-show="showfull">
        <p>{{item.info}}</p>
    </div>
    <hr/>
</div>

and in the controller I've added a function :

$scope.expand = function(e) {
    e.showfull = !e.showfull;
    //TODO: put here a foreach logic to hide all other items
}

But even without the foreach logic this is not working, the item don't show the additionnal div when clicked. I have two question :

  1. I suppose this is due to item being "passed by copy" in the expand function or some kind of scope isolation issue but can you explain me why in detail ? SOLVED

  2. How can I hide all the additional div of other items when I click an item and show the additionnal content for this item ? Do I need to do a directive ? NOT SOLVED

Thanks

I have a ng-repeat which display a list of divs and when I click on one it shows an aditionnal div for the clicked item.

This is working

<div ng-repeat="item in items">

    <div ng-click="showfull = !showfull">
        <div>
            <h1>{{item.title}}</h1>
            <p>{{item.content}}</p>
        </div>
    </div>
    <div ng-show="showfull">
        <p>{{item.info}}</p>
    </div>
    <hr/>
</div>

My items are loaded from a json containing a list of item and each item have a default attribut showfull set to false in this json. This is working, but now I want to hide all others item in the list when an item is clicked. I've tryied something like this :

This is not working

<div ng-repeat="item in items">

    <div ng-click="expand(item)">
        <div>
            <h1>{{item.title}}</h1>
            <p>{{item.content}}</p>
        </div>
    </div>
    <div ng-show="showfull">
        <p>{{item.info}}</p>
    </div>
    <hr/>
</div>

and in the controller I've added a function :

$scope.expand = function(e) {
    e.showfull = !e.showfull;
    //TODO: put here a foreach logic to hide all other items
}

But even without the foreach logic this is not working, the item don't show the additionnal div when clicked. I have two question :

  1. I suppose this is due to item being "passed by copy" in the expand function or some kind of scope isolation issue but can you explain me why in detail ? SOLVED

  2. How can I hide all the additional div of other items when I click an item and show the additionnal content for this item ? Do I need to do a directive ? NOT SOLVED

Thanks

Share Improve this question edited Oct 16, 2014 at 15:54 dekajoo asked Oct 16, 2014 at 15:34 dekajoodekajoo 2,1121 gold badge26 silver badges36 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 4

I think you're on the right track. You need to set the showfull on the item and then use ng-show or ng-if to hide it, or as Gavin mentioned, use a class.

On ng-click you can call your expand function, where you pass the item, toggle it and set all others to hidden.

Template:

<div ng-repeat="item in items>
    <div ng-click="expand(item)">
        <div>
            <h1>{{item.title}}</h1>
            <p>{{item.content}}</p>
        </div>
    </div>
    <div ng-show="item.showfull">
        <p>{{item.info}}</p>
    </div>
    <hr/>
</div>

Controller:

$scope.expand = function (item) {
    angular.forEach($scope.items, function (currentItem) {
        currentItem.showfull = currentItem === item && !currentItem.showfull;
    });
};

Your expand method is modifying the item, so your ng-show needs to reference the item:

<div ng-show="item.showfull">
    <p>{{item.info}}</p>
</div>

To hide all of your items you need to do something like

$scope.expand = function(item) {
   angular.forEach(items, function(i) {
       if (i === item) {
           i.showfull = !i.showfull;
       } else {
           i.showfull = false;
       }
    });
};

Shouldn't the second div you want to show be referencing the item?

<div ng-repeat="item in items>

    <div ng-click="expand(item)">
        <div>
            <h1>{{item.title}}</h1>
            <p>{{item.content}}</p>
        </div>
    </div>
    <!-- Added item to ng-show -->
    <div ng-show="item.showfull"> 
        <p>{{item.info}}</p>
    </div>
    <hr/>
</div>
发布评论

评论列表(0)

  1. 暂无评论