Ahmad Al-kheat
Ahmad Al-kheat

Reputation: 1795

Angular.js second controller does not work.

I have the following HTML file :

<!DOCTYPE html>
<html ng-app="store">
<head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
    <script type="text/javascript" src="app.js"></script>
</head>

<body ng-controller="storeController as store">
<ul class="list-group">
    <li class="list-group-item" ng-repeat="product in store.product">
        <h3>
            {{product.name}}
            <em class="pull-right"> {{product.price | currency}}</em>
        </h3>
        <section ng-controller="tabController as tabCtrl">
            <ul class="nav nav-pills">
                <li ng-class="{active:tab===1}"> <a href ng-click="tabCtrl.setTab(1)"> Description</a> </li>
                <li ng-class="{active:tab===2}"> <a href ng-click="tab =2"> Reviews</a> </li>
                <li ng-class="{active:tab===3}"> <a href ng-click="tab =3"> Specs</a> </li>
            </ul>

            <div class="panel" ng-show="tab === 1">
                <h4> Description</h4>
                <p>{{product.description}}</p>
            </div>
            <div class="panel" ng-show="tab === 2">
                <h4> Reviews</h4>
                <blockquote>Not yet</blockquote>
            </div>
            <div class="panel" ng-show="tab === 3">
                <h4> Specifications</h4>
                <blockquote>Not yet</blockquote>
            </div>

        </section>
    </li>
</ul>



</body>
</html>

And here is the app.js that has the Angular Module and controllers :

(function(){
var app = angular.module("store",[]);
var gem = [
    {
    name: "Dodec",
    price: 2.95,
    canPurchase: true,
    soldOut: false
    },
    {
    name: "Panta",
    price: 20.4,
    canPurchase: true,
    soldOut: false
    }
];
app.controller("storeController",function(){
    this.product = gem;
});

app.controller("tabController",function(){
    this.tab = 1;
    this.SetTab = function(value){
        this.tab = value;
    };
});


})();

The problem is the HTML is not reading the second controller, tabController, and therefore this.tab = 1 is not initializing tab to 1 , neither does the setTab function work.

PLease help, what did I get wrong ?

Upvotes: 1

Views: 732

Answers (2)

dfsq
dfsq

Reputation: 193261

The problem is quite simple: this is your ngClick handler:

ng-click="tabCtrl.setTab(1)"

and this is how you are defining controller function:

this.SetTab = function(value) {
    this.tab = value;
};

Note, that in javascript setTab is not the same as SetTab.

Another problem. If you chose to go with controller as syntax you should also fix ngClass and ngShow directives to use controller instance tab property, rather then $scope property:

ng-class="{active: tabCtrl.tab === 3}"

and

<div class="panel" ng-show="tabCtrl.tab === 2">
    <h4>Reviews</h4>
    <blockquote>Not yet</blockquote>
</div>

Demo: http://plnkr.co/edit/8WOzHCuFaJzgSNTy5X0i?p=preview

Upvotes: 2

SoluableNonagon
SoluableNonagon

Reputation: 11755

This is not an "answer", but more of a best practice when using "this". You might want to initialize 'this' to a variable and modify it later in the controller as such to make sure you are in the correct scope.

Ex:

app.controller("storeController",function(){
    var self = this;
    self.product = gem;
});

app.controller("tabController",function(){
    var self = this;
    self.tab = 1;
    self.SetTab = function(value){
        self.tab = value;
    };
});

Now, to address the question, try using $scope instead of 'this'

app.controller("storeController",function($scope){
    $scope.product = gem;
});

app.controller("tabController",function($scope){
    $scope.tab = 1;
    $scope.SetTab = function(value){
        $scope.tab = value;
    };
});

Upvotes: 2

Related Questions