0

I have two lists, one with names of "groups" and another with names of "items". It should change contents of list of items when another group is selected.

<div class="headers">
    <div id="header-1">Header 1</div>
    <div id="header-2 selected">Header 2</div>
</div>
<div class="contents">
    <div id="contents-2-1">Сontents 2.1</div>
    <div id="contents-2-2">Сontents 2.2</div>
</div>

Currently I've monkey-coded it as two controllers interacting via a service, but it's certainly not an Angular-idiomatic way to do that.

It would be easily solvable if each #header-n contained all the #contents-n-* inside of it, so that scoping rules would be enough to implement required behaviour. The problem is it's impossible to do so.

Another way would be to do it like in an Angular todomvc example via list filtering. Combined quantity of all the items over all groups is high enough to discard this option.

How do I implement such group selection in an idiomatic way?

UPD. The data are looking like this:

var groups = [
    {
        text: 'group 1',
        items: [1, 2, 3]
    },
    ...
];
var items = [
    {
        id: 1,
        text: 'item 1'
    },
    ...
];
7
  • 1
    Can we see how your data looks? Without it, this is all speculation. Commented Jul 14, 2015 at 15:26
  • good preparation of input data, then ng-repeat and groupBy. And style it as a ul li lists. Commented Jul 14, 2015 at 15:27
  • So based on that data - what are you trying to do? List the items under each group heading from the corresponding item id? Commented Jul 14, 2015 at 15:32
  • @tymeJV When a certain group is selected, all the items in that group should be displayed in contents div. Only one group can be selected at the same time. Commented Jul 14, 2015 at 15:34
  • Mmk, you can make that work, one sec. Commented Jul 14, 2015 at 15:41

1 Answer 1

1

You should be able to make that work - assuming you have some kind of $scope var for selected group (which is the object)

$scope.selectGroup = function(group) {
    $scope.selectedGroup = group; //lets say group 1
    $scope.groupItems = items.filter(function(item) {
        return $scope.selectedGroup.items.indexOf(item.id) > -1;
    });
}

And the HTML:

<div class="headers">
    <div id="header-1" ng-class=" {'selected': selectedGroup.text == group.text }" ng-click="selectGroup(group)" ng-repeat="group in groups">{{group.text}}</div>
</div>
<div class="contents">
    <div id="contents-2-1" ng-repeat="item in groupItems">{{item.text}}</div>
</div>

Demo: http://jsfiddle.net/HB7LU/15275/

(This assumes "groups" is accessible to repeat over)

Sign up to request clarification or add additional context in comments.

2 Comments

I see, I didn't need to put that groupItems into a service to make Angular render HTML when that variable changes. $scope has a kind of setter method that is called when any field of that object changes, hasn't it?
@polkovnikov.ph -- groupItems will need to be tied to the scope somehow - if the data changes in the service make sure that the scope is updated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.