2014-11-11 15 views
6

Come è possibile utilizzare un nome recuperato dal mio database come nomefile templateUrl?Angolare e UI-Router, come impostare un modello dinamico Url

Ho provato questo:

$stateProvider.state('/', { 
    url: '/', 
    views: { 
    page: { 
     controller: 'HomeCtrl', 
     templateProvider: function($templateFactory, $rootScope) { 
     console.log("$rootScope.template") 
     return $templateFactory.fromUrl('/templates/' + $rootScope.template); 
     } 
    } 
    } 
}); 

che non sembra funzionare il lavoro se il mio $ rootScope.template proviene da una query di database. Non so perché, ma non funziona.

Se nel mio controller faccio $ rootScope.template = "whatever.html" tutto funziona bene, ma se interrogo il template dal database non succede nulla. console.log ("$ rootScope.template") in templateProvider non mi dà nulla (la query funziona perfettamente).

La query richiede troppo tempo e non è quindi pronta per il router o cosa sta succedendo qui?

Che sto sbagliando e come posso risolverlo?

+0

Forse siete confusi su come gestire le richieste asincrone? Se si modifica la linea di registrazione su questo: 'console.log (" $ rootScope.template = "+ $ rootScope.template)' è vuoto? – wvdz

+0

Nah, mi spiace che "" sia lì per caso perché ho appena digitato rapidamente le ultime righe qui senza copiare/incollare .. Ho scritto correttamente nel mio codice ma non cambia nulla (come puoi vedere è correttamente scritto nella riga successiva ... – QlliOlli

risposta

8

come discusso in questo Q & A: Angular UI Router: decide child state template on the basis of parent resolved object, possiamo farlo in questo modo

Questo potrebbe essere un servizio di giochi di ruolo di "da Server/DB nome di modello di carico":

.factory('GetName', ['$http', '$timeout', 
    function($http, $timeout) { 
     return { 
     get : function(id) { 
      // let's pretend server async delay 
      return $timeout(function(){ 
      // super simplified switch... but ... 
      var name = id == 1 
        ? "views.view2.html" 
        : "views.view2.second.html" 
        ; 
      return {templateName : name}; 
      }, 500); 
     }, 
     }; 
    } 
]); 

Poi il defintion templateProvider sarebbe simile a questa:

views: { 
    "page": { 
     templateProvider: function($http, $stateParams, GetName) { 

     // async service to get template name from DB 
     return GetName 
      .get($stateParams.someSwitch) 
      // now we have a name 
      .then(function(obj){ 
       return $http 
        // let's ask for a template 
        .get(obj.templateName) 
        .then(function(tpl){ 
         // haleluja... return template 
         return tpl.data; 
       });  
      }) 

     }, 

il codice dovrebbe essere auto esplicativo. Controllare questo answer e il suo plunker per maggiori dettagli

+0

Ok, questo lavoro - ci sono quasi. Ora il mio problema è come ottenere quel pezzo di testo che mi serve (il nome del mio modello) dal mio database al templateProvider ... lo faccio restituire $ http.get ("/ api/mysites") nel servizio 'GetName'.Quindi in templateProvider obj = GetSite.get(). Ora, come posso accedere a questi dati all'interno di questa promessa? se console.log obj ottengo le cose promettenti (e trovo i miei dati sotto lo stato $$ o qualsiasi altra cosa). Quindi non posso trasformare quel materiale scaduto dai tuoi servizi in una vera chiamata da un database che restituirebbe il mio valore necessario. – QlliOlli

+0

Questo plunker aggiornato dovrebbe mostrare come: http://plnkr.co/edit/kGvrPdINl7M0WoHZGnyU?p=preview. Il punto è che cariciamo i dati dal server (il trucco qui è qualche chiamata per un 'dataFromServer.json'). Dovrebbe essere un metodo 'GetById' ... restituire la stringa nella vita ... ma qui è buono. Una volta arrivato, lo prendiamo e restituiamo il nome del modello corrispondente. Aiuta? –

+1

Ho cercato di spiegare il punto in un'altra risposta, mirando al "problema" con come gestire la reale risposta $ http. Questo ha aiutato? –

2

ho creato un esempio, che non utilizzare alcuni json di essere carico come dati dal server, controllare che here. Questo ciò che il $http riceverete (nel nostro examle simplifed)

// dataFromServer.json 
{ 
    "1": "views.view2.html", 
    "2": "views.view2.second.html" 
} 

Quindi ciò avverrà tramite $ http e noi lo userà per restituire il nome

.factory('GetName', ['$http', '$timeout', 
    function($http, $timeout) { 
     return { 
     get : function(id) { 
      // let's get data via $http 
      // here it is the list, but 
      // should be some GetById method 
      return $http 
      .get("dataFromServer.json") 
      .then(function(response){ 

       // simplified converter 
       // taking the $http result and 
       // by id gets the name 
       var converter = response.data; 
       var name = converter[id]; 

       return {templateName : name}; 
      }); 
     }, 
     }; 
} 

Come si può vedere, questo tempo, abbiamo davvero andare per i dati del server, utilizzando $http il trucco di nuovo è quello di ritorno che promettono

return $http // see the return 
    .get.... 

e più tardi, torniamo ancora una volta ... all'interno dell'allora

.... 
.then(function(response){ 
    ... 
    return {templateName : name}; 
}); 

Che Example is here

Problemi correlati