ng-disabled no evaluado después del cambio de datos

Estoy escribiendo una aplicación donde el usuario puede actualizar componentes pagando con dinero del juego. Después de presionar el button "actualizar", se envía una request ajax al server y se actualiza el componente. Después de eso estoy emitiendo otra request ajax para recuperar la página de nuevos componentes. Pero mientras se actualizan los datos, ng-disabled no se vuelve a verificar, por lo que el button de actualización sigue siendo seleccionable cuando no debería. Volver a cargar la página o la ruta corrige esto. Pero volver a cargar la página no es una buena experiencia para el usuario.

Estoy haciendo este proyecto para aprender Angularjs, así que si hay algo mal en mi configuration o cómo hago algo, ¡por favor díganme!

Intento include todo el código relevante; si falta algo, puede verlo en este enlace con el usuario y la contraseña "testing".

Para una cabecera, en machine-overview.html el button llama a upgradeComponent en el controller.js controller.js MachineOverviewCtrl emitiendo una request Ajax y al actualizar con éxito $scope.user y $scope.machine , los datos modificados se reflejan en la vista ( ng-repeat ) pero los botones ng-disabled no se evalúan y mantienen el estado anterior.

¿Qué estoy haciendo mal? ¿Cómo puedo forzar una evaluación o hacer la actualización de una manera que a Angularjs le gusta?

editar:

A la respuesta de @jack.the.ripper le falta el punto de que hay varios botones, uno por cada ng-repeat, pero esos botones solo no evalúan su directiva ng-disable.

imagen de ejemplo

//editar

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-bordenetworking"> <!--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 y su origen:

 $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({ networkingirectTo: '/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(); }); } }]); 

3 Solutions collect form web for “ng-disabled no evaluado después del cambio de datos”

Tu principal problema es que estás interpolando ng-disabled lugar de proporcionarle una expresión angular. Ver la definición de arguments en la documentation . Interpolando (usando {{}} ) la expresión hace que la expresión se evalúe solo una vez dentro de la directiva ng-disabled .

Simplemente cambia:

 <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> 

a

 <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> 

su escenario: cuando un usuario hace clic en un button, lo desactiva, y cuando se completa su operación, desea volver al button para habilitarlo.

lo que debería hacer es crear una directiva que administre el estado del button mientras el button realiza la operación, ¡no importa qué operación está haciendo …!

Baign dijo que una posible respuesta a su problema podría ser utilizar promises y devolver una promise en sus events de "clic", de esa manera puede configurar el button para deshabilitar "true" cuando el usuario click él y lo habilite nuevamente cuando su promise llegue resuelto.

eche un vistazo a esta directiva:

 angular.module('app').directive('clickState', [ function() { return { priority:-1, restrict: 'A', scope: { clickState: '&' }, link: function postLink(scope, element, attrs) { element.bind('click', function(){ element.prop('disabled', true); scope.clickState().finally(function() { element.prop('disabled', false); }); }); } }; } ]); 

uso:

 <button click-state="updateMachine()" type="submit">submit</button> 

controller:

 var p = $q.defer() $scope.updateMachine = function() { $http.get('api/machine.php').success(function(data) { $scope.machine = data; p.resolve(); //it could be p.resolve(data); to pass the data with the promise }); return p.promise() } 

Al leer $ scope. $ Apply y $ scope. $ Watch encontré la solución a esto: cuando cambio el order de mis requestes, todo funciona. Porque al actualizar los datos de usuario (como dinero) no hay una actualización activada para la tabla de la máquina. Cambiar el código para la primera actualización $ scope.user y después de eso $ scope.machine resuelve este problema. Estoy haciendo esta wiki de la comunidad.

  • telerik radGrid - persistir el estado del cliente en sort / paging / filter
  • ¿Cómo puedo alternar un ng-show en AngularJS basado en un boolean?
  • Carga dinámica de directivas con AngularJS - Error: Acceso a URI restringido denegado
  • Eclipse: qué proyecto elegir para crear un proyecto HTML / Javascript
  • cómo formatear html después de upload files y leer la respuesta json del server php
  • Problema de IE: foco de tabs incorrecto
  • jQuery UI Buttonset no agrega classs a elementos secundarios
  • Pantalla completa Google Map
  • (javascript / else / noscript iframe) para networkingucir el procesamiento del server?
  • 5 cuadros de selección, ocultar valores en cada elemento seleccionado
  • Matriz de JavaScript desde PHP
  • Javascript tiene muchos buenos JS marco (como Node.js AngularJS Vue.js React.js) es el mejor lenguaje de script.