AngularJS - Làm cách nào để sử dụng $ routeParams trong việc tạo templateUrl?


96

Ứng dụng của chúng tôi có điều hướng 2 cấp. Chúng tôi muốn sử dụng AngularJS $routeProviderđể cung cấp động các mẫu cho một <ng-view />. Tôi đã nghĩ đến việc làm điều gì đó dọc theo dòng này:

angular.module('myApp', []).
config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/:primaryNav/:secondaryNav', {
        templateUrl: 'resources/angular/templates/nav/'+<<primaryNavHere>>+'/'+<<secondaryNavHere>>+'.html'
    });
}]);

Tôi chỉ không biết làm thế nào để điền các phần trong <<>>. Tôi biết chínhNav và phụNav bị ràng buộc với $ routeParams, nhưng làm cách nào để truy cập $ routeParams tại đây để tự động phân phát mẫu?

Câu trả lời:


84

Tôi không thể tìm ra cách tiêm và sử dụng $routeParamsdịch vụ (mà tôi cho rằng sẽ là giải pháp tốt hơn). Tôi đã thử cách này và nghĩ rằng nó có thể hoạt động:

angular.module('myApp', []).
    config(function ($routeProvider, $routeParams) {
        $routeProvider.when('/:primaryNav/:secondaryNav', {
            templateUrl: 'resources/angular/templates/nav/'+$routeParams.primaryNav+'/'+$routeParams.secondaryNav+'.html'
        });
    });

Điều này dẫn đến lỗi này:

Nhà cung cấp không xác định: $ routeParams từ myApp

Nếu điều gì đó như vậy không thể thực hiện được, bạn có thể thay đổi templateUrlthành trỏ đến một tệp HTML một phần vừa có ng-includevà sau đó đặt URL trong bộ điều khiển của bạn bằng cách sử dụng $routeParamnhư sau:

angular.module('myApp', []).
    config(function ($routeProvider) {
        $routeProvider.when('/:primaryNav/:secondaryNav', {
            templateUrl: 'resources/angular/templates/nav/urlRouter.html',
            controller: 'RouteController'
        });
    });

function RouteController($scope, $routeParams) {
        $scope.templateUrl = 'resources/angular/templates/nav/'+$routeParams.primaryNav+'/'+$routeParams.secondaryNav+'.html';
    }

Với cái này là của bạn urlRouter.html

<div ng-include src="templateUrl"></div>

7
Vấn đề tại sao trước đây không hoạt động đã được ghi lại groups.google.com/forum/?fromgroups=#!topic/angular/qNi5lqm-Ps8 . Vì mục tiêu tiêm đến config()chỉ các nhà cung cấp được chuyển, không phải các trường hợp dịch vụ thực tế chẳng hạn như $routePrams.
nre

18
Bạn thực sự không phải tạo "tệp html một dòng" - chỉ cần sử dụng khóa "template:" thay vì "templateUrl" và cung cấp cho nó một chuỗi chứa html one-liner ;-)
DominikGuzei

1
Bạn không thể chỉ sử dụng templatethay vì templateUrl?
kaiser

1
Điều này thực sự sẽ hoạt động, nhưng còn việc áp dụng bộ điều khiển cho từng mẫu được chọn thì sao? Sử dụng phương pháp này sẽ để lại cho bạn chỉ với một bộ điều khiển "bậc thầy": "RouteController"
Yaniv Efraim

9
nếu bạn thiết lập templateđể một chức năng, bạn có thể vượt qua $routeParamsthành chức năng: $routeProvider.when('/:pNav/:sNav', { template: fn($routeParams) { return $routeParams.pNav + '/' + $routeParams.sNav + '.html' } });. Tuy nhiên, bạn không thể tự động xác định một bộ điều khiển theo cách này :(
jacob

131

Tính năng rất hữu ích này hiện có sẵn bắt đầu từ phiên bản 1.1.2 của AngularJS. Nó được coi là không ổn định nhưng tôi đã sử dụng nó (1.1.3) và nó hoạt động tốt.

Về cơ bản, bạn có thể sử dụng một hàm để tạo chuỗi templateUrl. Hàm được chuyển các tham số tuyến đường mà bạn có thể sử dụng để xây dựng và trả về chuỗi templateUrl.

var app = angular.module('app',[]);

app.config(
    function($routeProvider) {
        $routeProvider.
            when('/', {templateUrl:'/home'}).
            when('/users/:user_id', 
                {   
                    controller:UserView, 
                    templateUrl: function(params){ return '/users/view/' + params.user_id; }
                }
            ).
            otherwise({redirectTo:'/'});
    }
);

Rất cảm ơn https://github.com/lrlopez về yêu cầu kéo.

https://github.com/angular/angular.js/pull/1524


5
Điều này hiện đã được hỗ trợ đầy đủ trong 1.2 và nó có lẽ là cách tốt nhất: docs.angularjs.org/api/ngRoute/provider/$routeProvider
Stu

những gì về một bộ điều khiển động dựa trên các tham số?
Oak

Làm ơn, vui lòng (làm ơn!) Cho tôi biết rằng điều này có thể làm được với controllers...?
Cody

làm cách nào để truy cập bộ điều khiển từ mẫu trong trường hợp này (do $ routeProvider cung cấp)? Thông thường, nếu bộ điều khiển bị ràng buộc bởi chỉ thị ng-controller = "myController", bạn có thể tham chiếu myController dưới dạng myCtrl. Làm cách nào để xác định myCtrl trong trường hợp này?
FlavorScape

@FlavorScape Tôi cũng vừa gặp sự cố này - giải pháp là thực hiện điều gì đó như $ routeProvider.when ("/ foo", {controller: "FooController", controllerAs: "foo", templateUrl: "foo.html"});
Erin Drummond

18

templateUrl có thể được sử dụng như một chức năng với URL đã tạo trả về. Chúng ta có thể thao tác với url bằng cách truyền đối số nhận routeParams.

Xem ví dụ.

.when('/:screenName/list',{
    templateUrl: function(params){
         return params.screenName +'/listUI'
    }
})

Hy vọng điều này giúp đỡ.


7

Được rồi, nghĩ là tôi hiểu rồi ...

Thông tin cơ bản đầu tiên: Lý do tôi cần điều này là gắn Angular lên trên Node Express và nhờ Jade xử lý các phần của tôi cho tôi.

Vì vậy, đây là những gìchya phải làm ... (uống bia và dành hơn 20 giờ cho nó trước !!!) ...

Khi bạn thiết lập mô-đun của mình, hãy lưu $routeProvidertoàn cục:

// app.js:
var routeProvider
    , app = angular.module('Isomorph', ['ngResource']).config(function($routeProvider){

        routeProvider = $routeProvider;
        $routeProvider
            .when('/', {templateUrl: '/login', controller: 'AppCtrl'})
            .when('/home', {templateUrl: '/', controller: 'AppCtrl'})
            .when('/login', {templateUrl: '/login', controller: 'AppCtrl'})
            .when('/SAMPLE', {templateUrl: '/SAMPLE', controller: 'SAMPLECtrl'})
            .when('/map', {templateUrl: '/map', controller: 'MapCtrl'})
            .when('/chat', {templateUrl: '/chat', controller: 'ChatCtrl'})
            .when('/blog', {templateUrl: '/blog', controller: 'BlogCtrl'})
            .when('/files', {templateUrl: '/files', controller: 'FilesCtrl'})
            .when('/tasks', {templateUrl: '/tasks', controller: 'TasksCtrl'})
            .when('/tasks/new', {templateUrl: '/tasks/new', controller: 'NewTaskCtrl'})
            .when('/tasks/:id', {templateUrl: '/tasks', controller: 'ViewTaskCtrl'})
            .when('/tasks/:id/edit', {templateUrl: '/tasks', controller: 'EditTaskCtrl'})
            .when('/tasks/:id/delete', {templateUrl: '/tasks', controller: 'DeleteTaskCtrl'})
        .otherwise({redirectTo: '/login'});

});

// ctrls.js
...
app.controller('EditTaskCtrl', function($scope, $routeParams, $location, $http){

    var idParam = $routeParams.id;
    routeProvider.when('/tasks/:id/edit/', {templateUrl: '/tasks/' + idParam + '/edit'});
    $location.path('/tasks/' + idParam + '/edit/');

});
...

Đó có thể là nhiều thông tin hơn những gì cần thiết ...

  • Về cơ bản, bạn sẽ muốn lưu trữ $routeProvidervar của Mô-đun trên toàn cầu, ví dụ như routeProviderđể Bộ điều khiển của bạn có thể truy cập nó.

  • Sau đó, bạn chỉ có thể sử dụng routeProvidervà tạo một tuyến đường MỚI (bạn không thể 'ĐẶT LẠI tuyến đường' / 'Quảng cáo lại'; bạn phải tạo một tuyến đường mới), tôi chỉ thêm dấu gạch chéo (/) ở cuối để nó có ngữ nghĩa là người đầu tiên.

  • Sau đó (bên trong Bộ điều khiển của bạn), đặt templateUrlchế độ xem bạn muốn nhấn.

  • Lấy ra thuộc controllertính của .when()đối tượng, vì sợ rằng bạn sẽ nhận được một vòng lặp yêu cầu vô hạn.

  • Và cuối cùng (vẫn bên trong Controller), sử dụng $location.path()để chuyển hướng đến tuyến đường vừa được tạo.

Nếu bạn quan tâm đến cách đưa một ứng dụng Angular vào một ứng dụng Express, bạn có thể fork repo của tôi tại đây: https://github.com/cScarlson/isomorph .

Và phương pháp này cũng cho phép bạn giữ Liên kết dữ liệu hai chiều AngularJS trong trường hợp bạn muốn liên kết HTML với cơ sở dữ liệu của mình bằng cách sử dụng WebSockets: nếu không, nếu không có phương pháp này, các liên kết dữ liệu Angular của bạn sẽ chỉ xuất ra {{model.param}}.

Nếu bạn sao chép nó vào lúc này, bạn sẽ cần mongoDB trên máy của mình để chạy nó.

Hy vọng điều này giải quyết vấn đề này!

Cody

Đừng uống nước tắm của bạn.


3

Bộ định tuyến: -

...
.when('/enquiry/:page', {
    template: '<div ng-include src="templateUrl" onload="onLoad()"></div>',
    controller: 'enquiryCtrl'
})
...

Bộ điều khiển: -

...
// template onload event
$scope.onLoad = function() {
    console.log('onLoad()');
    f_tcalInit();  // or other onload stuff
}

// initialize
$scope.templateUrl = 'ci_index.php/adminctrl/enquiry/'+$routeParams.page;
...

Tôi tin rằng đó là một điểm yếu trong anglejs mà $ routeParams KHÔNG hiển thị bên trong bộ định tuyến. Một cải tiến nhỏ sẽ tạo ra một thế giới khác biệt trong quá trình thực hiện.


3

Tôi đã hỗ trợ thêm cho điều này trong ngã ba của góc cạnh của tôi. Nó cho phép bạn chỉ định

$routeProvider
    .when('/:some/:param/:filled/:url', {
          templateUrl:'/:some/:param/:filled/template.ng.html'
     });

https://github.com/jamie-pate/angular.js/commit/dc9be174af2f6e8d55b798209dfb9235f390b934

không chắc điều này sẽ được chọn vì nó là loại chống lại hạt cho góc cạnh, nhưng nó hữu ích đối với tôi


Đúng rồi! Havent đã sử dụng nó nhưng THỰC SỰ cần nó. Có bất kỳ cảnh báo nào khác mà tôi nên đề phòng không? Ngoài ra, bất kỳ từ nào trên Angular triển khai nó? - Tôi thích sử dụng CDN.
Cody

Không có ý kiến, tôi chưa bao giờ ký giấy tờ nên việc này đi vào ngõ cụt, nhưng bạn có thể nhận thay đổi và cố gắng lấy lại nó (Tôi không còn làm việc ở công ty mà tôi đã làm cùng khi tôi làm điều này, và họ không theo đuổi angularjs thêm nữa)
Jamie Pate

Được rồi, cảm ơn vì thông tin và đóng góp của bạn cho vấn đề - Tôi sẽ giải quyết vấn đề đó và giải quyết vấn đề sau một phút.
Cody

1
//module dependent on ngRoute  
 var app=angular.module("myApp",['ngRoute']);
    //spa-Route Config file
    app.config(function($routeProvider,$locationProvider){
          $locationProvider.hashPrefix('');
          $routeProvider
            .when('/',{template:'HOME'})
            .when('/about/:paramOne/:paramTwo',{template:'ABOUT',controller:'aboutCtrl'})
            .otherwise({template:'Not Found'});
    }
   //aboutUs controller 
    app.controller('aboutCtrl',function($routeParams){
          $scope.paramOnePrint=$routeParams.paramOne;
          $scope.paramTwoPrint=$routeParams.paramTwo;
    });

trong index.html

<a ng-href="#/about/firstParam/secondParam">About</a>

firstParam và secondParam có thể là bất cứ thứ gì theo nhu cầu của bạn.


0

Tôi đang gặp sự cố tương tự và được sử dụng $stateParamsthay vìrouteParam

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.