2014-11-16 8 views
8

All'interno della mia app AngularJS ho una vista con un JQuery datatable, controller per gestire i dati caricati nel datatable come mostrato di seguito. Quando si aggiorna la vista, i dati vengono caricati senza un problema nel datatable, ma se cambio rotta in un'altra vista, si ritorna alla vista con datatable ricevo il messaggio (nessun dato disponibile nella tabella) ... dopo aver tracciato il problema che ho trovato ciò accade perché il datatable viene caricato prima che la chiamata $ http ritorni. Ho provato ad aggiungere naif sul div contenente il datatable per impedirne la visualizzazione a meno che non ci siano dati restituiti ma senza fortuna poiché ha funzionato solo la prima volta che carico la pagina (tramite aggiornamento) ma non funzionerebbe sul cambio di rotta. Qualcuno può dirmi per favore cosa esattamente sto facendo qui e come risolvere questo problema? Grazie

app.js

$stateProvider.state('app.allmembers', { 
      url: '/members/members-list', 
      templateUrl: 'tpl/members/membersList.html' 
}) 

Controller.js

.controller('MembersListController', ['$scope', '$http', 'GlobalService', function($scope, $http, GlobalService) { 

     $scope.dset = []; 

     $scope.getMembersList = function() { 

     var memURL = 'http://localhost:3000/apiserv/members/'; 

     $http({ method:'GET', 
       url: memURL, 
       headers: { 'Content-Type' : 'application/json' 
       }     
      }) 
     .success(function(data,status,headers,config){ 
       $scope.dset = data; 

       $scope.tbOptions = { 
            data: $scope.dset, 
            aoColumns: [ 
            { mData: 'title' }, 
            { mData: 'firstName' }, 
            { mData: 'lastName' }, 
            { mData: 'email' }       
            ], 
            aoColumnDefs: [ 
            { 
             aTargets: [ 3 ], 
             mRender: function (data, type, full) { 
             return '<a href="mailto:' + data + '" style=color:red;>' + data + '</a>'; 
             }        
            }, 
            { 
             aTargets: [ 1 ], 
             mRender: function (data, type, full) { 
             return '<a href="#/app/members/update-member/' + full._id + '" style=color:blue;>' + data + '</a>'; 
             }        
            } 
            ]      
       }; 

       console.log(data); 
      } 
     }).error(function(data,status,headers,config){ 
      console.log(status); 
     }); 



     }; 

    }]) 

membersList.html

<div class="wrapper-md" ng-controller="MembersListController" ng-init="getMembersList()"> 
    <div class="row"> 
    <div class="col-sm-10"> 
     <div class="panel panel-default"> 
     <div class="panel-body"> 
       <div class="table-responsive"> 
        <table ui-jq="dataTable" ui-options="tbOptions" class="table table-striped m-b-none"> 
        <thead> 
         <tr> 
         <th style="width:15%">Title</th> 
         <th style="width:30%">First Name</th> 
         <th style="width:30%">Last Name</th> 
         <th style="width:25%">Email</th> 
         </tr> 
        </thead> 
        <tbody> 
        </tbody> 
        </table> 
       </div> 
     </div> 
     </div> 
    </div> 
    </div> 
</div> 
+0

Non vedo dove viene visualizzato il messaggio "Nessun dato disponibile nella tabella". Inoltre, potresti inserire la tua istruzione ng-if nel codice di esempio? – Aidin

+2

È possibile utilizzare una promessa per assicurarsi che i dati siano pronti prima di visualizzare i dati, o utilizzare una soluzione nel percorso delle app. – rbinsztock

+0

@Aidin Non visualizzo il messaggio "Nessun dato disponibile nella tabella" questo fa parte dei datatables, inserito il ng-if before e ancora non ha funzionato – MChan

risposta

0

tbOptions configurazione iniziale, e insieme oggetto di dati in caso di successo:

.controller('MembersListController', ['$scope', '$http', 'GlobalService', function ($scope, $http, GlobalService) { 
    $scope.tbOptions = { 
     data: [], 
     aoColumns: [ 
      { mData: 'title' }, 
      { mData: 'firstName' }, 
      { mData: 'lastName' }, 
      { mData: 'email' } 
     ], 
     aoColumnDefs: [ 
      { 
       aTargets: [3], 
       mRender: function (data, type, full) { 
        return '<a href="mailto:' + data + '" style=color:red;>' + data + '</a>'; 
       } 
      }, 
      { 
       aTargets: [1], 
       mRender: function (data, type, full) { 
        return '<a href="#/app/members/update-member/' + full._id + '" style=color:blue;>' + data + '</a>'; 
       } 
      } 
     ] 
    }; 

    $scope.getMembersList = function() { 
     var memURL = 'http://localhost:3000/apiserv/members/'; 
     $http({ 
      method: 'GET', 
      url: memURL, 
      headers: { 
       'Content-Type': 'application/json' 
      } 
     }) 
     .success(function (data, status, headers, config) { 
      $scope.tbOptions.data = data; 
      console.log(data); 
     }).error(function (data, status, headers, config) { 
      console.log(status); 
     }); 
    }; 
    $scope.getMembersList(); 
}]) 

Inoltre, evitare ng-init. Inizializza all'interno della funzione di costruzione. Quindi rimuovi ng-init dal tuo HTML.

+0

Purtroppo l'ho provato prima e funzionerà solo con la prima volta che viene caricata la vista, se provi a cambiare percorso ad un'altra pagina e poi torni alla pagina con il datatable non mostrerà più dati – MChan

3

È possibile utilizzare Angular directive per Jquery Datatable anziché utilizzare altre opzioni. Sarà utile per aggiungere funzionalità in Angular way.

URL: http://l-lin.github.io/angular-datatables/

Si prega di verificare il seguente esempio, che vi aiuterà a completare l'operazione.

URL: http://l-lin.github.io/angular-datatables/#/withAjax

Inoltre, si prega di consultare il seguente API per corrispondenza le configurazioni

URL: http://l-lin.github.io/angular-datatables/#/api

lavoro Demo:http://plnkr.co/edit/fxkaowyvkyIgRNAgcClI?p=preview

Nota: È possibile che questo demo combinato con il modulo ui-router. Quindi credo che risolverà il tuo problema.

+0

Ho aggiornato il mio rispondi con la dimostrazione che quello che stai cercando – Asik

+0

questa direttiva per datatable ha una soluzione migliore per il caricamento dei dati: http://l-lin.github.io/angular-datatables/#/withPromise – Rasalom

0

MemberService.js

var MemberService = angular.module('MemberService', []); 

MemberService.factory('MemberFactory', ['$q', '$http', function ($q, $http) { 
    var memURL = 'http://localhost:3000/apiserv/members/'; 
    return { 
    getMembers: function() { 
     var deferred = $q.defer(); 
     $http({ 
     method: 'GET', 
     url: memURL, 
     headers: {'Content-Type': 'application/json'} 
     }).success(function (data, status, headers, config) { 
     console.log(data); 
     deferred.resolve(data); 
     }).error(function (data, status, headers, config) { 
     deferred.reject(status); 
     }); 
     return deferred.promise; 
    } 
    }; 
}]); 

app.js (non dimenticare di includere il modulo MemberService nella vostra dipendenza app)

var app = angular.module('application', ['MembersList', 'MemberService']); 

$stateProvider.state('app.allmembers', { 
    url: '/members/members-list', 
    templateUrl: 'tpl/members/membersList.html', 
    resolve: { 
    membersData: ['MemberFactory', function(MemberFactory { 
     return MemberFactory.getMembers(); 
    } 
    } 
}) 

memberListCtrl.js

var MembersList = angular.module('MembersList', []); 

MembersList.controller('MembersListController', ['$scope', 'GlobalService', 'membersData' function ($scope, GlobalService, membersData) { 

    $scope.tbOptions = { 
    data: membersData, 
    aoColumns: [ 
     {mData: 'title'}, 
     {mData: 'firstName'}, 
     {mData: 'lastName'}, 
     {mData: 'email'} 
    ], 
    aoColumnDefs: [ 
     { 
     aTargets: [3], 
     mRender: function (data, type, full) { 
      return '<a href="mailto:' + data + '" style=color:red;>' + data + '</a>'; 
     } 
     }, 
     { 
     aTargets: [1], 
     mRender: function (data, type, full) { 
      return '<a href="#/app/members/update-member/' + full._id + '" style=color:blue;>' + data + '</a>'; 
     } 
     } 
    ] 
    }; 
}]); 

qui la gist: https://gist.github.com/senayar/d2e2b09fdf475088a71d

Se si riscontrano ancora problemi, mostrare il servizio e il controller.

+0

Ho postato il mio codice su http://plnkr.co/edit/N8DdNoJYBvn2vv7i2ggA è lo stesso codice esatto che si sta utilizzando, tranne che ora, anche prima di implementare il codice del controller, ricevo un errore: Errore non rilevato: [$ injector: modulerr] Impossibile istanziare l'app del modulo a causa di: Errore: [$ injector: nomod] Module 'app' non è disponibile! Hai sbagliato a scrivere il nome del modulo o hai dimenticato di caricarlo. Se si registra un modulo, assicurarsi di specificare le dipendenze come secondo argomento. Qualche idea di cosa potrei mancare qui? Grazie – MChan

+0

il tuo plnkr non è utilizzabile. Angolare non è caricato e hai incluso tutte le tue librerie ma non aggiunto i loro file. Dichiara anche i tuoi componenti per modulo. Es: var MembersList = angular.module ('MembersList', []); quindi puoi scrivere MembersList.controller ('MembersListController', []); e ora aggiungi il tuo modulo nella tua app.js. Ho aggiornato la risposta per aiutarvi a – rbinsztock

+0

Mi dispiace ma sono un po 'confuso, solo per confermare che ho ragione, quindi aggiungerò MemberService alle dipendenze dell'app in app.js anche se app.services è già incluso come una dipendenza ... corretta? – MChan

0

Preferirei che tu usassi ngTableParams. Dai un'occhiata a questo. Table Params

app.controller('MembersListController', ['$scope', '$http', 'GlobalService',function($scope,$http, GlobalService,ngTableParams) { 

    data = []; 
    $scope.tableParams = new ngTableParams({ 
    page: 1, 
    count: 10, 
    sorting: { 
     name: 'asc'  // initial sorting 
    } 
}, { 
    counts: [], 
    getData: function ($defer, params) { 
     var orderedData = params.sorting() ? $filter('orderBy')(data, params.orderBy()) : data; 
     var searchedData = searchData(orderedData); 
     params.total(searchedData.length); 
     $scope.events = searchedData.slice((params.page() - 1) * params.count(), params.page() * params.count()); 
     if (params.total() < (params.page() - 1) * params.count()) params.page(1); 
     $defer.resolve($scope.events); 
    }, 
    $scope: { $data: {} } 
}); 

var searchData = function (orderedData) { 
    orderedData = $filter('filter')(orderedData); 
    if ($scope.searchText) 
     return $filter('filter')(orderedData, $scope.searchText); 
    return orderedData 
}; 
    $scope.getMembersList = function() { 

    var memURL = 'http://localhost:3000/apiserv/members/'; 

    $http({ method:'GET', 
      url: memURL, 
      headers: { 'Content-Type' : 'application/json' 
      }     
     }) 
    .success(function(data,status,headers,config){ 
      data = data; // This assigns the data into the array can be accessed through $data in page 

      //$scope.tbOptions = { 
      //     data: $scope.dset, 
      //     aoColumns: [ 
      //      { mData: 'title' }, 
      //      { mData: 'firstName' }, 
      //      { mData: 'lastName' }, 
      //      { mData: 'email' }       
      //     ], 
      //     aoColumnDefs: [ 
      //      { 
      //       aTargets: [ 3 ], 
      //       mRender: function (data, type, full) { 
      //       return '<a href="mailto:' + data + '" style=color:red;>' + data + '</a>'; 
      //       }        
      //      }, 
      //      { 
      //       aTargets: [ 1 ], 
      //       mRender: function (data, type, full) { 
      //       return '<a href="#/app/members/update-member/' + full._id + '" style=color:blue;>' + data + '</a>'; 
      //       }        
      //      } 
      //     ]      
      //}; 

      console.log(data); 
     } 
    }).error(function(data,status,headers,config){ 
     console.log(status); 
    }); 



    }; 

    }]) 

membersList.html

<div class="wrapper-md" ng-controller="MembersListController" ng-init="getMembersList()"> 
    <div class="row"> 
<div class="col-sm-10"> 
    <div class="panel panel-default"> 
    <div class="panel-body"> 
      <div class="table-responsive"> 
       <table ui-jq="dataTable" class="table table-striped m-b-none"> 
       <thead> 
        <tr> 
        <th style="width:15%">Title</th> 
        <th style="width:30%">First Name</th> 
        <th style="width:30%">Last Name</th> 
        <th style="width:25%">Email</th> 
        </tr> 
       </thead> 
       <tbody> 
        <tr ng-repeat="data in $data"> 
        <td>{{data.title}}</td> 
        <td>{{data.firstName}}</td> 
        <td>{{data.lastName}}</td> 
        <td>{{data.email}}</td> 
       </tr> 
       </tbody> 
       </table> 
      </div> 
    </div> 
    </div> 
</div> 

I ngTableParams utilizzati in .js pagina è fatto con ordine dal filtro, dati di ricerca in caso di una barra di ricerca è possibile ricercare il dati. Il tableParams viene ricaricato ogni volta per ottenere l'elenco dei dati.

Nella pagina i dati $ vengono utilizzati per accedere ai dati presenti nella variabile tableParams nell'ambito. ngTableParams carica molto più velocemente. Spero che questo aiuti