2013-02-28 9 views
7

Ho la seguente configurazione:Toggle visibilità di un ng-includere, a seconda rotta

$routeProvider 
.when('/cars', { templateUrl: 'app/cars/index.html', controller: 'CarsCtrl', reloadOnSearch: false }) 
.when('/bikes', { templateUrl: 'app/bikes/index.html', controller: 'BikesCtrl', reloadOnSearch: false }); 

e da qualche parte nel mio radice index.html v'è una:

<a href="#/cars">Cars</a> 
<a href="#/bikes">Bikes</a> 
<div ng-view></div> 

Ora, voglio che sia le viste caricate e generate nel DOM allo stesso tempo e ne mostrano una a seconda del percorso/URL.

Qualcosa come il seguente (codice di lavoro non effettivo, solo per darti un'idea).

app.js:

$routeProvider 
.when('/cars', { controller: 'CarsCtrl', reloadOnSearch: false }) 
.when('/bikes', { controller: 'BikesCtrl', reloadOnSearch: false }); 

radice index.html:

<a href="#/cars">Cars</a> 
<a href="#/bikes">Bikes</a> 
<div ng-include="'app/cars/index.html'" ng-show="carsVisible"></div> 
<div ng-include="'app/bikes/index.html'" ng-show="bikesVisible"></div> 

UPDATE: so che ng-view tipo di fa questo, ma la differenza, se sottile, esiste . Voglio che l'html di ogni vista sia generato una volta e rimanga nel DOM in ogni momento.

+0

Non è possibile eseguire questa operazione con ng-view. Ma la domanda è, perché vorresti davvero farlo. È perché vorresti "pre-processare" ogni percorso in modo che si carichi più velocemente? Il routing è già piuttosto veloce, a meno che i controller non richiedano dati asincroni, nel qual caso si utilizzerebbe la 'risoluzione' all'interno dell'oggetto di definizione del percorso, oltre a qualche codice di inizializzazione dell'app per il recupero dei dati asincroni in background. – Stewie

risposta

9

ho creato un unico RouteCtrl per caricare tutti i vostri punti di vista tramite ng-includere. ng-view non è usato. Ho disegnato i modelli. I modelli potrebbero contenere le proprie direttive del controller ng per inserire controller specifici.

<body ng-controller="RouteCtrl"> 
    <a href="#/cars">Cars</a> 
    <a href="#/bikes">Bikes</a> 
    <div ng-controller="RouteCtrl"> 
     <div ng-include="'/cars.html'" ng-show="carsVisible"></div> 
     <div ng-include="'/bikes.html'" ng-show="bikesVisible"></div> 
    </div> 

    <script type="text/ng-template" id="/cars.html"> 
    Cars template. 
    </script> 
    <script type="text/ng-template" id="/bikes.html"> 
    Bikes template. 
    </script> 

$ routeProvider è ancora configurato, ma non è specificato alcun modello o di controllo, causando il RouteCtrl di essere sempre attivo. Quel controller ascolta l'evento $routeChangeSuccess e modifica le proprietà ng-show di conseguenza.

app.config(function($routeProvider) { 
    $routeProvider 
    .when('/cars', {}) 
    .when('/bikes', {}) 
}); 

app.controller('RouteCtrl', function($scope, $route, $location) { 
    $scope.$on('$routeChangeSuccess', function() { 
    var path = $location.path(); 
    console.log(path); 
    $scope.carsVisible = false; 
    $scope.bikesVisible = false; 
    if(path === '/cars') { 
     $scope.carsVisible = true; 
    } else if(path === '/bikes') { 
     $scope.bikesVisible = true; 
    } 
    }); 
}); 

Plunker

L'idea per questa soluzione da @Andy.

1

Invece di utilizzare ng-include, è necessario utilizzare ng-view;

Questo mostrerà il contenuto di una o app/cars/index.htmlapp/bikes/index.html

<a href="#/cars">Cars</a> 
<a href="#/bikes">Bikes</a> 
<div ng-view></div> 

Vedere la Template sezione dalla http://docs.angularjs.org/tutorial/step_07

+0

Ciao Pascal, grazie per la tua risposta! Tuttavia, questo non è quello che sto cercando. Ho fatto un chiarimento nella mia domanda. ng-view cambierà il contenuto, sì, ma lo fa rimuovendo il contenuto dalla vista in uscita e inserendo il contenuto per la nuova vista, ogni volta che cambia il percorso. Voglio avere entrambi i contenuti già renderizzati e basta attivare uno o l'altro con un display ng-show o CSS. – luisfarzati

+0

dove/quando cambierai 'carsVisible' e' bikesVisible ', e hai un controller da qualche parte nella root' index.html'? –

1

Utilizzare un servizio con una direttiva spettacolo:

<div ng-show="myService.isActive('/')">Show this when at default route</div> 
<div ng-show="myService.isActive('/cars')">Show this when at cars</div> 

Servizio:

myApp.factory('MyService', 
    function ($location) { 
     return { 
      isActive: function (path) { 
       return (($location.path() == path)); 
      } 
     } 
    } 
); 

App.JS:

// this is run after angular is instantiated and bootstrapped 
myApp.run(function ($rootScope, myService) { 
    $rootScope.breadcrumbService = MyService; 
}); 
3

ho trovato un altro modo, che credo sia il più semplice, più veloce e più gestibile:

How to set bootstrap navbar active class with Angular JS?

Quale è:

Usa ng-controller per eseguire un singolo controller al di fuori della ng-view:

<div class="collapse navbar-collapse" ng-controller="HeaderController"> 
    <ul class="nav navbar-nav"> 
     <li ng-class="{ active: isActive('/')}"><a href="/">Home</a></li> 
     <li ng-class="{ active: isActive('/dogs')}"><a href="/dogs">Dogs</a></li> 
     <li ng-class="{ active: isActive('/cats')}"><a href="/cats">Cats</a></li> 
    </ul> 
</div> 
<div ng-view></div> 

e includere in co ntrollers.js:

function HeaderController($scope, $location) 
{ 
    $scope.isActive = function (viewLocation) { 
     return viewLocation === $location.path(); 
    }; 
}