2013-02-28 30 views
7

Mam następującą konfigurację:widoczność Przegubowe z ng obejmują w zależności od trasy

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

i gdzieś w moim korzenia index.html znajduje się:

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

Teraz chcę zarówno widoki są ładowane i generowane w DOM w tym samym czasie i pokazują jeden z nich w zależności od trasy/adresu URL.

Coś jak poniżej (nie faktyczny działający kod, żeby dać ci pomysł).

app.js:

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

korzeń 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: Wiem, że ng-view niby to robi, ale różnica, czy subtelne, istnieje . Chcę, aby html każdego widoku był generowany raz i pozostawał w DOM przez cały czas.

+0

Nie można tego zrobić za pomocą ng-view. Ale pytanie brzmi: dlaczego tak naprawdę chcesz to zrobić. Czy to dlatego, że chcesz "przetworzyć" każdą trasę, aby ładowała się szybciej? Routing jest już dość szybki, chyba że twoje kontrolery wymagają pewnych danych asynchronicznych, w takim przypadku użyjesz "rozwiązania" wewnątrz obiektu definicji trasy oraz kodu inicjalizacji aplikacji do pobierania asynchronicznych danych w tle. – Stewie

Odpowiedz

9

stworzyłem jeden RouteCtrl załadować wszystkich swoich poglądów poprzez ng obejmują. ng-view nie jest używany. Wprowadziłem szablony. Szablony mogą zawierać własne dyrektywy ng-kontrolerów do ściągania określonych kontrolerów.

<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 jest nadal skonfigurowany, ale nie określono szablonu ani kontrolera, co powoduje, że RouteCtrl jest zawsze aktywny. Ten kontroler nasłuchuje zdarzenia $routeChangeSuccess i odpowiednio manipuluje właściwościami ng-show.

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

Ideą tego rozwiązania jest od @Andy.

1

Zamiast używać ng-include, należy użyć ng-view;

Spowoduje to wyświetlenie zawartości albo app/cars/index.html lub app/bikes/index.html

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

Zobacz Template sekcję z http://docs.angularjs.org/tutorial/step_07

+0

Cześć Pascal, dziękuję za odpowiedź! Jednak tego nie szukam. W moim pytaniu wyjaśniłem. ng-view przełączy zawartość, tak, ale robi to poprzez usunięcie zawartości z widoku wychodzącego i wstawienie zawartości do nowego widoku za każdym razem, gdy zmienia się trasa. Chcę mieć już renderowaną obie treści i po prostu przełączać się między nimi za pomocą wyświetlacza ng-show lub CSS. – luisfarzati

+0

gdzie/kiedy zmieniasz 'carsVisible' i' bikesVisible ', i czy masz kontroler gdzieś w katalogu głównym' index.html'? –

1

skorzystać z usługi z dyrektywy przedstawiają:

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

Usługa:

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

Znalazłem inny sposób, który moim zdaniem jest to najprostszy, najszybszy i najbardziej opanowania:

How to set bootstrap navbar active class with Angular JS?

który jest:

Zastosowanie ng-sterownik, aby uruchomić jeden kontroler poza widokiem Ng:

<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> 

i dołącz do co ntrollers.js:

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