2013-04-18 13 views
12

Sto tentando di implementare un'interfaccia utente classica elenco/dettagli. Quando si fa clic su un elemento nell'elenco, desidero visualizzare un modulo di modifica per quell'articolo mentre continua a visualizzare l'elenco. Sto cercando di aggirare la limitazione di 1-visualizzazione per pagina di Angular e ho deciso di farlo collegando tutti gli URL allo stesso controller/vista. (Forse questo è la radice del mio problema e io sono aperto a soluzioni alternative.)AngularJS: visualizzazioni multiple con routing senza perdita di ambito

Routing:

$routeProvider 
    .when('/list', { templateUrl: '/Partials/Users.html', controller: UserController }) 
    .when('/edit/:UserId', { templateUrl: '/Partials/Users.html', controller: UserController }) 
    .otherwise({ redirectTo: '/list' }); 

La vista (/Partials/Users.html):

<!-- List of users --> 
<div ng-repeat="user in Users"> 
    <a href="*/edit/{{ user.Id }}">Edit {{ user.Name }}</a> 
</div> 

<!-- Edit form --> 
<div> 
    {{ SelectedUser.Name }} 
</div> 

controller :

function UserController($scope, $routeParams) { 
    // the model for the list 
    $scope.Users = GetUserListFromService(); 

    // the model for the edit form 
    if ($routeParams.UserId != null) 
     $scope.SelectedUser = GetUserFromService($routeParams.UserId); 
} 

Problemi:

  1. Quando si fa clic su un collegamento di modifica, il controller viene ripristinato con un nuovo ambito, quindi devo riavviare l'elenco degli utenti. (In un esempio più complesso potrei avere un input dell'utente memorizzato legato al modello e questo andrebbe anche perso.) Preferirei mantenere lo scope dal percorso precedente.
  2. Preferirei utilizzare un controller separato (o, come molti altri sviluppatori angolari si sono lamentati, la possibilità di avere più viste visualizzate!) Ma questo porta allo stesso problema di perdere l'ambito.
+0

possibile duplicato di [Angularjs, passaggio di ambito tra percorsi] (http://stackoverflow.com/questions/13882077/angularjs-passing-scope-between-routes) –

risposta

14

Provare a utilizzare il router: http://github.com/angular-ui/ui-router.

Essi hanno nidificato di vista e la gestione dello stato più facile di quanto angolare di routing di default :-)

+1

Grazie! Non è stato facile seguire i loro tutorial e campioni, quindi per gli altri che cercano di implementare lo stesso pattern ti suggerisco di creare uno "stato" per ogni vista e utilizzare gli stati nidificati per consentire la condivisione dell'ambito. – Keith

+0

Mi piacerebbe vedere come hai fatto questo. Sto avendo problemi a percorrere la stessa strada con questa scelta di router. – Timothy

+2

@timothy https://github.com/dotJEM/angular-routing è un'alternativa al router UI che ha un semplice approccio alle viste (nessuna roba magica con viste @ viste ecc ... solo una semplice e semplice denominazione di tutti visualizzazioni) ... Se questa è stata la causa del tuo problema (il modello di visualizzazione dell'interfaccia utente-router ha ricevuto un bel po 'di critica, e molti sembrano avere difficoltà a usarlo al di là dei casi molto semplici) – Jens

1

ho trovato Angular Multi View di essere una manna dal cielo per questo scenario. Permette di conservare l'ambito mentre il percorso cambia e consente a più controllori di condividere lo stesso percorso senza nidificare le viste.

Raccomando Multi vista angolare se avete più di 2 viste sulla vostra pagina. Altrimenti, quando si utilizza ui-router, l'annidamento di più viste diventa molto veloce.

7

Più viste non sono supportate nel core AngularJS. È possibile utilizzare questa libreria per questo scopo che supporta qualsiasi quantità di punti di vista nidificate sulla pagina, dove ogni livello è configurato in modo indipendente con un proprio controllore e modello:

http://angular-route-segment.com

E 'molto più semplice da usare rispetto UI- router. Esempio di configurazione può apparire come segue:

$routeSegmentProvider. 

when('/section1',   's1.home'). 
when('/section1/prefs', 's1.prefs'). 
when('/section1/:id',  's1.itemInfo.overview'). 
when('/section1/:id/edit', 's1.itemInfo.edit'). 
when('/section2',   's2'). 

segment('s1', { 
    templateUrl: 'templates/section1.html', 
    controller: MainCtrl}). 

within(). 

    segment('home', { 
     templateUrl: 'templates/section1/home.html'}). 

    segment('itemInfo', { 
     templateUrl: 'templates/section1/item.html', 
     controller: Section1ItemCtrl, 
     dependencies: ['id']}). 

    within(). 

     segment('overview', { 
      templateUrl: 'templates/section1/item/overview.html'}). 

     segment('edit', { 
      templateUrl: 'templates/section1/item/edit.html'}). 

     up(). 

    segment('prefs', { 
     templateUrl: 'templates/section1/prefs.html'}). 

    up(). 

segment('s2', { 
    templateUrl: 'templates/section2.html', 
    controller: MainCtrl}); 
0

mi si avvicinò con lo stesso problema e ho personnaly non amano i plugin quando non sono assolutamente inevitabile. Ho appena spostato la parte singleton in un servizio.

Nel mio caso ci sono: id [/: mode] percorsi e voglio reagire in modo diverso se l'utente cambia anche solo la modalità o l'id. Quindi, devo conoscere l'ID precedente.

Quindi, c'è un servizio con metodo di attivazione che aggiorna il suo stato. E l'ambito viene reinizializzato ogni volta con il seguente codice.

module.controller('MyController', ['$scope', '$routeParams', 'navigator', function($scope, $routeParams, navigator) { 
    var id = null; 
    var mode = null; 

    if (typeof($routeParams.id)!='undefined') 
    { 
     id = $routeParams.id; 
    } 

    if (typeof($routeParams.mode)!='undefined') 
    { 
     mode = $routeParams.mode; 
    } 

    navigator.activate(id, mode); 

    $scope.items = navigator.items; 
    $scope.activeItem = navigator.activeItem; 
    $scope.modes = navigator.modes; 
    $scope.activeMode = navigator.activeMode; 
}]); 

Nel metodo activate posso confrontare id activeItem.id del singleton e reagire diversamente.

Problemi correlati