3

I asked this question before and was wondering maybe somebody has had a similar problem and maybe know how to deal with it? My plnkr!

Angular tabs are not working with ng-repeat. It seems that Angular can't put together tab value from click and tab value from ng-show. My code:

<section ng-app="myApp">
<div ng-controller="myCtrl">
    <ul ng-init="tab=1">
        <li ng-repeat="item in data">
          <a href ng-click="tab = item.thingy">{{item.name}}</a>
        </li>
    </ul>
    <div ng-repeat="item in data" ng-show="tab === item.thingy">
        <img ng-src="{{item.img}}" width="50px"><br>
        {{item.year}}</div>
</div>
</section>
var app = angular.module('myApp', []);

app.controller('myCtrl', ['$scope', function($scope) {
  $scope.data = [{
    name: "First",
    title: "oneTitle",
    description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
    year: "2013",
    img: "http://static.hdw.eweb4.com/media/wp_400/1/5/42735.jpg",
    thingy: 1
  }, {
    name: "third",
    title: "twoTitle",
    description: "Quisque pulvinar libero sed eros ornare",
    year: "2014",
    img: "http://static.hdw.eweb4.com/media/wp_400/1/1/8519.jpg",
    thingy: 2
  }, {
    name: "Second",
    title: "threeTitle",
    description: "Cras accumsan massa vitae tortor vehicula .",
    year: "2015",
    img: "http://static.hdw.eweb4.com/media/wp_400/1/5/43326.jpg",
    thingy: 3
  }, {
    name: "fourth",
    title: "FourTitle",
    description: "Suspendisse vitae mattis magna.",
    year: "2011",
    img: "http://static.hdw.eweb4.com/media/wp_400/1/5/42413.jpg",
    thingy: 4
   }];
}]);
2
  • I don't really know the answer to this but what I can do is recommend using UI-Bootstrap's tabs which work perfectly fine using this type of behaviour Commented May 15, 2015 at 8:34
  • Thanks! Will try. But I can't stand not knowing the reason for this setup not working :) Commented May 15, 2015 at 8:36

3 Answers 3

5

There are multiple ways to approach this (one is dcodesmith's great answer).

Use Controller As syntax

If you wish to define view-only variables on your view (as you did in your example), use the Controller As syntax.

One of the pros you'll get using this approach is direct access to define and modify variables on the controller's scope. while in your case, the tab variable has been modified on the child scopes of ng-repeat / ng-init


html

<div ng-controller="myCtrl as vm">

    <ul ng-init="vm.tab=1">
        <li ng-repeat="item in vm.data">
          <a href ng-click="vm.tab = item.thingy">{{item.name}}</a>
        </li>
    </ul>

    <div ng-repeat="item in vm.data" ng-show="vm.tab === item.thingy">
        <img ng-src="{{item.img}}" width="50px"><br>
        {{item.year}}</div>
</div>

js

app.controller('myCtrl', ['$scope',
  function($scope) {
    var vm = this;

    vm.data = [{
       name: "First",
       title: "oneTitle",
       description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
       year: "2013",
       img: "http://static.hdw.eweb4.com/media/wp_400/1/5/42735.jpg",
       thingy: 1
     },
     //...
    ];

  }
]);

http://plnkr.co/edit/1q0AVrcqhIZRjFvVSVIP?p=preview

enter image description here

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

4 Comments

We dont need following line <div ng-repeat="item in vm.data" ng-show="vm.tab === item.thingy">
@VirendraShenviVelingkar this provided in the OP example. what you are suggesting is to keep the object itself instead of the index. i agree this is better however, i stay loyal to the OP example :)
:) Yeah you are right, I thought making the code more clean. :p Lets be loyal to the OP example.
I love you guys! Seriously!
3

Firstly, I think you should declare/initialise your $scope.tab in the controller, as well as the function to set the selected tab. Best practise IMO.

NOTE: Adopting this way of doing also helps testing easier.

HTML

    <ul>
        <li ng-repeat="item in data">
          <a href="#" ng-click="setTab(item.thingy)">{{item.name}}</a>
        </li>
    </ul>

JS

$scope.tab = 1;

// for the debugging reason. 
$scope.$watch('tab', function (newTab, oldTab) {
    console.log(newTab, oldTab);
});

$scope.setTab = function (pos) {
  $scope.tab = pos;
}

Comments

1

modifications in script.js:

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

app.controller('myCtrl', ['$scope', function ($scope) {
    $scope.data = [{
        name: "First",
        title: "oneTitle",
        description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
        year: "2013",
        img: "http://static.hdw.eweb4.com/media/wp_400/1/5/42735.jpg",
        thingy: 1
    }, {
        name: "third",
        title: "twoTitle",
        description: "Quisque pulvinar libero sed eros ornare",
        year: "2014",
        img: "http://static.hdw.eweb4.com/media/wp_400/1/1/8519.jpg",
        thingy: 2
    }, {
        name: "Second",
        title: "threeTitle",
        description: "Cras accumsan massa vitae tortor vehicula .",
        year: "2015",
        img: "http://static.hdw.eweb4.com/media/wp_400/1/5/43326.jpg",
        thingy: 3
    }, {
        name: "fourth",
        title: "FourTitle",
        description: "Suspendisse vitae mattis magna.",
        year: "2011",
        img: "http://static.hdw.eweb4.com/media/wp_400/1/5/42413.jpg",
        thingy: 4
    }];

  $scope.details = $scope.data[0];

  $scope.GetDetails = function(obj)
  {
    $scope.details = obj;
  }

}]
);

In HTML:

<div ng-controller="myCtrl">
        <ul ng-init="tab=1">
            <li ng-repeat="item in data">
              <a href ng-click="GetDetails(item);">{{item.name}}</a>
            </li>
        </ul>
        <div>
          {{details.thingy}} <br/>
          {{details.name}}<br/>
          {{details.title}}<br/>
          {{details.description}}<br/>
          {{details.year}}<br/>
          <img ng-src="{{details.img}}" width="50px"><br>
        </div>
</div>

Comments

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.