2013-02-28 16 views
7

Tôi đã cấu hình như sau:Chuyển đổi tầm nhìn của một ng-bao gồm tùy thuộc vào tuyến đường

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

và đâu đó trong thư mục gốc của tôi index.html có một:

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

Bây giờ, tôi muốn cả hai lượt xem được tải và tạo trong DOM cùng một lúc và hiển thị một trong số chúng tùy thuộc vào tuyến đường/URL.

Giống như sau (không phải mã thực tế, chỉ để cung cấp cho bạn ý tưởng).

app.js:

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

gốc 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> 

CẬP NHẬT: Tôi biết rằng ng xem loại thực hiện điều này, nhưng sự khác biệt, nếu tinh tế, tồn tại . Tôi muốn html của mỗi lần xem được tạo ra một lần và luôn ở trong DOM.

+0

Không thể thực hiện điều này bằng chế độ xem ng. Nhưng câu hỏi là, tại sao bạn thực sự muốn làm điều này. Có phải vì bạn muốn 'tiền xử lý' mỗi tuyến đường để tải nhanh hơn không? Định tuyến đã khá nhanh, trừ khi bộ điều khiển yêu cầu một số dữ liệu không đồng bộ, trong trường hợp này bạn sẽ sử dụng 'giải quyết' bên trong đối tượng định nghĩa tuyến đường, cộng với một số mã khởi tạo ứng dụng để tìm nạp dữ liệu không đồng bộ trong nền. – Stewie

Trả lời

9

Tôi tạo ra một RouteCtrl duy nhất để tải tất cả các quan điểm của bạn thông qua ng-bao gồm. ng-view không được sử dụng. Tôi đã phác thảo các mẫu. Các mẫu có thể chứa các chỉ thị ng-controller riêng của chúng để kéo các bộ điều khiển cụ thể.

<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 vẫn được định cấu hình, nhưng không có mẫu hoặc bộ điều khiển nào được chỉ định, khiến RouteCtrl luôn hoạt động. Bộ điều khiển đó lắng nghe sự kiện $routeChangeSuccess và điều khiển các thuộc tính ng-show cho phù hợp.

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

Ý tưởng cho giải pháp này là từ @Andy.

1

Thay vì sử dụng ng-include, bạn nên sử dụng ng-view;

này sẽ hiển thị nội dung của một trong hai app/cars/index.html hoặc app/bikes/index.html

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

Xem Template đoạn từ http://docs.angularjs.org/tutorial/step_07

+0

Xin chào Pascal, cảm ơn bạn đã trả lời! Tuy nhiên, đây không phải là những gì tôi đang tìm kiếm. Tôi đã làm rõ trong câu hỏi của mình. ng-view sẽ chuyển đổi nội dung, vâng, nhưng nó thực hiện bằng cách xóa nội dung khỏi khung nhìn thoát và chèn nội dung cho khung nhìn mới, mỗi lần thay đổi lộ trình. Tôi muốn có cả hai nội dung đã được trả lại và chỉ chuyển đổi một hoặc một với một hiển thị ng-show hoặc CSS. – luisfarzati

+0

nơi/khi nào bạn thay đổi 'carsVisible' và' bikesVisible ', và bạn có một bộ điều khiển ở đâu đó trong thư mục gốc' index.html'? –

1

Sử dụng một dịch vụ với một chỉ thị cho thấy:

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

dịch vụ:

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

tôi tìm thấy một cách khác, mà tôi nghĩ là đơn giản nhất, nhanh nhất và dễ quản lý nhất:

How to set bootstrap navbar active class with Angular JS?

Đó là:

Dùng ng-điều khiển để chạy một đơn bộ điều khiển bên ngoài 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> 

và bao gồm trong đồng ntrollers.js:

function HeaderController($scope, $location) 
{ 
    $scope.isActive = function (viewLocation) { 
     return viewLocation === $location.path(); 
    }; 
} 
Các vấn đề liên quan