I am writing an app where the user can upgrade components paying with ingame money. After pressing the upgrade-button an ajax request is send to the server and upgrades the component. After that I am issuing another ajax request to retrieve the new components page. But while the data gets updated, ng-disabled is not checked again, so the upgrade-button remains clickable when it should not. Reloading page or route fixes this. But reloading the page is no good user experience.
I am doing this project to learn the Angularjs way, so if there is anything wrong in my setup or how I do something, please tell me!
I try to include all relevant code, if something is missing, you can view it under this link with user and password test.
For a headstart, in machine-overview.html
the button calls upgradeComponent
in controller.js
controller MachineOverviewCtrl
issuing an Ajax request and on success updating $scope.user
and $scope.machine
, changed data is reflected in the view (ng-repeat
) but the buttons ng-disabled
is not evaluated and keeps the old state.
What am I doing wrong? How can I force an evaluation or do the update in a way Angularjs likes it?
edit:
@jack.the.ripper's answer is missing the point, that there are multiple buttons, one for every ng-repeat, but those buttons only don't evaluate their ng-disable directive.
//edit
index.html
<!DOCTYPE html>
<html lang=de ng-app=hacksApp>
<head>
<!--ommited includes (angularjs, bootstrap etc)-->
</head>
<body ng-controller=hacksUserCtrl>
<!--ommited navbar-->
<div ng-view></div>
</body>
</html>
machine-overview.html
<!--ommited divs-->
<table class=table table-bordered>
<!--ommited thead-->
<tbody>
<tr ng-repeat=component in machine | object2Array | orderBy:'ComponentID'><!--converting objects to arrays, issue appears with and without filter-->
<!--ommited other irrelevant td-->
<td>
<button
ng-disabled=
{{
(component.price_next <= 0) || (component.price_next > user.values.euro) ||
(user.values.energy_remaining < (component.energy_next-component.energy))
}}
ng-click=upgradeComponent(component) class=btn btn-danger role=button>
Upgrade {{component.text}} for <span class=glyphicon glyphicon-euro></span> {{component.price_next}}
</button>
</td>
</tr>
</tbody>
</table>
<!--ommited divs-->
javascript vars and their origin:
$scope.user.x //hacksUserCtrl
$scope.machine.x //MachineOverviewCtrl
app.js
var hacksApp = angular.module('hacksApp', [
'ngRoute',
'hacksControllers',
'hacksFilters',
]);
hacksApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/machine', {
templateUrl: 'html/machine-overview.html',
controller: 'MachineOverviewCtrl',
activetab: 'machine'
}).
when('/jobs', {
templateUrl: 'html/jobs-overview.html',
controller: 'JobsOverviewCtrl',
activetab: 'jobs'
}).
when('/phones/:phoneId', {
templateUrl: 'html/phone-detail.html',
controller: 'PhoneDetailCtrl',
activetab: 'phone'
}).
otherwise({
redirectTo: '/machine'
});
}]);
controller.js
var hacksControllers = angular.module('hacksControllers', ['hacksFilters']);
hacksControllers.controller('hacksUserCtrl', ['$scope', '$http', '$interval', '$route',
function ($scope, $http, $interval, $route) {
$scope.$route = $route;
$scope.updateUser = function() {
$http.get('api/user.php').success(function(data) {
$scope.user = data;
if(!$scope.user.loggedIn){
window.location = index.php;
}
});
}
$scope.updateUser();
$interval($scope.updateUser, 60000);
}]);
hacksControllers.controller('MachineOverviewCtrl', ['$scope', '$http', '$interval',
function ($scope, $http, $interval) {
$scope.machine = [];
$scope.updateMachine = function() {
$http.get('api/machine.php').success(function(data) {
$scope.machine = data;
});
}
$scope.updateMachine();
$interval($scope.updateMachine, 60000);
$scope.upgradeComponent = function(component){
var params = {name: component.name};
$http({
method: 'POST',
url: 'api/machine-upgrade.php',
data: $.param(params),
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).success(function(data) {
$scope.updateMachine();
$scope.updateUser();
});
}
}]);