Eylen
Eylen

Reputation: 2677

Reload a list with angularjs

I'm just starting to play with angularJS, so maybe I'm asking something easy to do, but I can't find the way to do it. The situation is the following: I have a list that's populated by an ng-repeat taking the values from a scoped controller variable. This variable is loaded on page load by an jsonp call, and this works fine. The problem comes when I need to reload this list based on another select. For example, if a select 'day' value in the select I need to show some values and when I select 'week' I need to show others (also loaded via ajax).

What I've tried is to have a service that loads the data and returns it, and in the controller have two methods, one for the first load and another for the second one that does $scope.apply with the variable. I then call this second method on select value change (I've done it with jquery to simplify it until I can fix this).

This is part of my HTML

<div x-ng-controller='LeaderboardCtrl'>
    <select id='leaderboard-select'>
        <option value='day'>day</option>
        <option value='week'>week</option>
        <option value='month'>month</option>
    </select>
    <div x-ng-repeat='p in leaderboard'>
        <p>{{p}}</p>
    </div>
</div>

And this is part of the code that affects this functionality

var lead = angular.module("lead",[]);

function LeaderboardCtrl($scope,$attrs,$http,jtlanService) {
    $scope.leaderboard = [];
    $scope.period = 'day';

    var data = {
        period:$scope.period
    };

    $scope.loadLeaderboard = function(){
        myService.loadLeaderboard(data).then(function(leaderboard) {
            $scope.leaderboard = [];
            $scope.leaderboard.push.apply($scope.leaderboard,leaderboard);
        });
    }

    $scope.reloadLeaderboard = function() {
        myService.loadLeaderboard(data).then(function(leaderboard) {
            $scope.$apply(function() {
                $scope.leaderboard = [];
                $scope.leaderboard.push.apply($scope.leaderboard,leaderboard);
            });
        });
    }

    $scope.loadLeaderboard()
}

lead.service("myService",["$http", function($http) {
    var myService = {
        loadLeaderboard : function(data) {
            var promise = $http.jsonp("/widget/leaderboardJSONP?callback=JSON_CALLBACK&_="+new Date(),{
                params:data,
                cache:false,
                ajaxOptions: { cache: false }
            }).then(function(response) {
                return response.data;
            });
            return promise;
        }
    };
    return myService;
}]);

$("#leaderboard-select").change(function(){
    scope.period = $("#leaderboard-select").val();
    scope.reloadLeaderboard();
});

Here's a fiddle with the code: http://jsfiddle.net/WFGqN/3/

Upvotes: 1

Views: 2826

Answers (1)

Langdon
Langdon

Reputation: 20073

Your fiddle is riddled with issues:

  1. There's no ng-app in your mark-up
  2. You need to change the second Framework Extensions dropdown to one of the "No wrap" options
  3. Your service needs to be defined above your controller
  4. Your controller is referencing "jtlanService" but you've defined "myService"
  5. Your $http.jsonp call isn't going to work as is, but you could use can use the echo service (see Ajax Requests on the left side) to emulate requests
  6. You can't and shouldn't be using jQuery events to call Angular controllers. You should use ng-change and not $().change (and even if you were using jQuery for event binding, you should be using $().on('change')).
  7. You didn't need to use $scope.$apply in your loadLeaderboard function, since when you're calling it, you were already inside of of an $apply call.
  8. There's no need for 2 load+reload leaderboard methods.
  9. And after all that, you don't actually need jQuery.

Here's a fiddle that fixes things up and I think gets you what you want: http://jsfiddle.net/WFGqN/5/. You'll of course need to fix the service on your end, but you get the idea.

I recommend reading this SO answer: "Thinking in AngularJS" if I have a jQuery background?

Upvotes: 2

Related Questions