2012-11-23 8 views
10

Al momento ho sviluppato una tabella di contenuti utilizzando AngularJS, la tabella popolerà sulla base di un servizio angolare "Modello", che richiama un servizio Web e restituisce la lista e l'utilizzo ng-repeat e la creazione di un tavolo e tutto il suo contenuto.modello aggiornamento e la rilegatura Update con UI

Tutto al momento funziona bene, ho un piccolo problema però. Parte della tabella, stiamo emettendo un pulsante di azione che quando viene cliccato richiama un servizio web che aggiorna il record corrente. Sto cercando di fare in modo che i dati dei record vengano aggiornati automaticamente, ma devo aggiornare la pagina per vedere le modifiche.

Ecco il mio codice

miei app.js

angular.module('my_vehicles', ['vehicleServices', 'AccountsDirectives']); 

service.js

'use strict'; 

angular.module('vehicleServices', ['ngResource']). 
    factory('Car', function($resource) { 
     return $resource('/vehicle/api/car.json/:id', {}, 
      { 
       query: {method:'GET',  isArray:false}, 
       delete: {method:'DELETE', isArray:false}, 
       update: {method:'PUT',  isArray:false} 
      } 
     ); 
}); 

controller.js

'use strict'; 

function MyVehicleController($scope, Car) { 

    var init = function() { 
     $scope.page_has_next = true; 
     $scope.cars = []; 
     $scope.page = 1; 
    }; 

    // initialize values 
    init(); 


    Car.query({my_vehicle: true}, 
     // success 
     function(data) { 
      $scope.page_has_next = data.has_next; 
      $scope.cars = data.objects; 
     }, 
     // error 
     function(data) { 

     } 
    ); 


    $scope.mark_sold = function(id, index) { 
     Car.update({ 
      id  : id, 
      status : 'S' 
     }, 
     function(data) { 

     }); 
    } 

    $scope.delete = function(id, index) { 
     Car.delete(
      {id: id}, 
      // on success 
      function() { 
       // remove the element from cars array and it will be 
       // automatically updated by ng-repeat 
       $scope.cars.splice(index, 1); 
       $scope.loadMore(1); 
      } 
     ); 
    } 

    $scope.is_total_zero = function() { 
     return !!($scope.cars.length) 
     //return $scope.cars.length > 0 ? true : false 
    } 


    $scope.loadMore = function(limit) { 
     if($scope.page_has_next) { 
      $scope.$broadcast('loading_started'); 
      console.log(limit); 
      Car.query({my_vehicle: true, page: $scope.page, limit: limit}, 
       // success 
       function(data) { 
        $scope.page_has_next = data.has_next; 
        $scope.cars = $scope.cars.concat(angular.fromJson(data.objects)); 
        $scope.page++; 
        $scope.$broadcast('loading_ended'); 
       }, 
       // error 
       function() { 
        $scope.page_has_next = false; 
        $scope.$broadcast('loading_ended'); 
       } 
      ); 
     } 
    } 


    $scope.$on('loading_started', function() { 
     $scope.state = 'loading'; 
    }); 

    $scope.$on('loading_ended', function() { 
     $scope.state = 'ready'; 
    }); 


} 

e, infine, il mio codice html

    <tr ng-repeat="car in cars"> 
         <td><a href="{% ng car.get_absolute_url %}">{% ng car._get_model_display.make_display %} {% ng car._get_model_display.model_display %} {% ng car._get_model_display.trim_display %}</a></td> 
         <td>{% ng car.created_at_format %}</td> 
         <td>{% ng car.view_count %}</td> 
         <td ng-model="car.status_label">{% ng car.status_label %}</td> 
         <td> 
          <div class="btn-group"> 
           <button ng-disabled="car.status == 'S' || car.status == 'P'" ng-model="edit" class="btn btn-mini edit-btn">{% trans 'Edit' %}</button> 
           <button ng-disabled="car.status == 'S'" ng-click="delete(car.id, $index)" class="btn btn-mini delete-btn">{% trans 'Delete' %}</button> 
           <button ng-disabled="car.status == 'S' || car.status == 'P'" ng-click="mark_sold(car.id, $index)" class="btn btn-mini edit-btn">{% trans 'Mark as sold' %}</button> 
          </div> 
          </td> 
         </tr> 

PS il {% ng XXX%} è l'output {{XXX}}, sto usando la sintassi di cui sopra, perché il motore di template Django non mi permette di utilizzare {{}} in modo ho sviluppato un templatetag che avrebbe uscita {{}} ..

Come accennato in precedenza, il mio problema è che ogni volta che invoco "contrassegno come venduto" invocherebbe il file cars.update() ma non aggiornerà il record visualizzato, deve aggiornare per vedere i cambiamenti. Qualche idea su come posso risolvere questo?

risposta

7

Per quanto comprendo il codice, si aggiorna il db senza aggiornare il modello di auto ($ scope.cars) in modo che le modifiche si riflettano solo nel db ma non nell'applicazione AngularJS.

magari provare il seguente:

$scope.mark_sold = function(id, index) { 
    Car.update({ 
     id  : id, 
     status : 'S' 
    }, 
    function(data) { 
     $scope.cars[id].status = 'S'; 
    }); 
} 
+0

ho appena dovuto sostituire $ scope.cars [id] con $ scope.cars [index] .. ecc .. ma questo è esattamente quello che mi serviva, grazie –

+0

@ MoJ.Mughrabi ah ok, mi è stato in ogni caso chiedevo perché avevi i due parametri: id e l'indice :) –

2

È necessario aggiornare anche l'array auto in memoria. hai già l'indice di matrice (secondo parametro della funzione mark_sold):

$scope.mark_sold = function(id, index) { 
    Car.update({ 
     id  : id, 
     status : 'S' 
    }, 
    function(data) { 
     // Update in-memory array 
     $scope.$apply(function(scope) { 
      scope.cars[index].status = 'S'; 
     }); 

    }); 
} 
+0

ho cercato di usare $ scope.apply, ma sono di errore (error: $ scope.apply non è una funzione) .. –

+0

scusa, errore mio, sostituisci con $ scope. $ apply. (Corretto) –

+1

non credo che è necessario per attivare la digestione manualmente. Se si modificano le proprietà dell'oscilloscopio (come le auto in questo caso) l'angolare lo riconosce automaticamente. –

Problemi correlati