b_it_s
b_it_s

Reputation: 704

angularJS: ui-router $state.go only works on first click

I'm trying to learn how to use AngularJS and I stumbled upon a problem I can't solve...

The code below should: - show 2 views: 1 to show some names ("receivers") on the left and one to show the main content (an intro or a list for the corresponding person ("currentReceiver")) - navigate via $state.go to the corresponding "wishlist" and changing the URL to ".../#/wishlist/"

The code I have seems to work only when I click on a name the first time... Once I've clicked once, the url stays empty ('.../#/') and the intro page is shown...

Can somebody explain me what I'm doing wrong or where I should look to debug this problem...?

Part of my index.html

    <div class="container-fluid">
        <div class="row">
            <div class="col-sm-3 col-md-2 sidebar" ui-view="wishlists">
            </div>
            <div class="col-sm-20 col-sm-offset-3 col-md-10 col-md-offset-2 main" ui-view="wishes">
            </div>
        </div>
    </div>

    <!-- scripts -->
    ...     

</body>

wishlist.tmpl.html (template of view 'wishlist' on left hand side wish link to functon "setCurrentReceiver")

<ul class="nav nav-sidebar">
    <li ng-repeat="receiver in receivers" ng-class="{'active': isCurrentReceiver(receiver)}">
        <a href="#" ng-click="setCurrentReceiver(receiver)">{{receiver.name}}</a>
    </li>
</ul>

gimmi-app.js (with $state.go in function setCurrentReceiver)

angular.module('Gimmi', [
    'ui.router',
    'wishlist',
    'wishlist.wish',
    'wishlist.receiver'
])
.config(function($stateProvider, $urlRouterProvider){
    $stateProvider
        .state('gimmi', {
            url: '',
            abstract: true
        })
    ;
    $urlRouterProvider.otherwise('/');
})

.controller('MainCtrl', function ($scope, $state) {
    //--------------------------------------------------
    // RECEIVER MODULE
    //--------------------------------------------------

    $scope.receivers = [
        {"id": 1, "name": "XXX", "age": 31, "gender": "m"},
        {"id": 2, "name": "YYY", "age": 28, "gender": "v"},
        {"id": 3, "name": "ZZZ", "age": 59, "gender": "v"},
    ];

    $scope.currentReceiver = null;

    function setCurrentReceiver(receiver) {
        $scope.currentReceiver = receiver;

        $state.go('gimmi.wishlist.wish', {receiverName: receiver.name});

        cancelEditing();
        cancelCreating();
    }

    function isCurrentReceiver(receiver) {
        return $scope.currentReceiver !== null && receiver.id === $scope.currentReceiver.id;
    }

    $scope.setCurrentReceiver = setCurrentReceiver;
    $scope.isCurrentReceiver = isCurrentReceiver;

    //--------------------------------------------------
    // WISHLIST MODULE
    //--------------------------------------------------

    $scope.wishes = [

        {"id": 1, "title": "Smartphone", "price": 250, "status": "reserved", "receiverID": 1},
        {"id": 2, "title": "Lamzac", "price": 75, "status": "free", "receiverID": 1},
        {"id": 3, "title": "Fatboy", "price": 140, "status": "free", "receiverID": 1},
        {"id": 4, "title": "Pioneer DJM 800", "price": 800, "status": "reserved", "receiverID": 1},
        {"id": 5, "title": "Snowboard", "price": 500, "status": "free", "receiverID": 2}

    ];

wishlist.js (with the view to show the left hand side and the intro page when url = '/')

angular.module('wishlist', [
    'gimmi.models.wishlist'
])
    .config(function($stateProvider){
        $stateProvider
            .state('gimmi.wishlist', {
                url: '/',
                views: {
                    'wishlists@': {
                        controller: 'wishlistCtrl',
                        templateUrl: 'app/wishlist/wishlist.tmpl.html'
                    }
                    ,'wishes@': {
                        controller: 'wishCtrl',
                        templateUrl: 'app/wishlist/intro.tmpl.html'
                    }
                }
            })
        ;
    })

    .controller('wishlistCtrl', function wishlistCtrl($scope){

    });
});

wish.js (the .js with the state to which I refer in $state.go)

angular.module('wishlist.wish', [
    'gimmi.models.wishlist',
    'gimmi.models.wish',
    'wishlist.wish.create',
    'wishlist.wish.edit'    
])
    .config(function($stateProvider){

        $stateProvider
            .state('gimmi.wishlist.wish', {
                url: 'wishlist/:receiverName',
                views: {
                    'wishes@': {
                        templateUrl: 'app/wishlist/wish/wish.tmpl.html',
                        controller:'wishCtrl'
                    }
                }
            })
        ;
    })

    .controller('wishCtrl', function($scope, $stateParams) {
        $scope.currentReceiverName = $stateParams.receiverName;
    })

;

Upvotes: 2

Views: 1139

Answers (1)

Dimitri Lavren&#252;k
Dimitri Lavren&#252;k

Reputation: 4879

You just need to remove the href="#" from the link.

Explanation: ng-click is bound to the onclick JavaScript event. Unless you return false or do event.preventDefault() the default behavior of the click will be executed and this is open the url defined in the href attribute.

Upvotes: 6

Related Questions