[javascript] AngularJS 동적 라우팅

현재 라우팅이 내장 된 AngularJS 애플리케이션이 있습니다. 작동하고 모든 것이 정상입니다.

내 app.js 파일은 다음과 같습니다.

angular.module('myapp', ['myapp.filters', 'myapp.services', 'myapp.directives']).
  config(['$routeProvider', function ($routeProvider) {
      $routeProvider.when('/', { templateUrl: '/pages/home.html', controller: HomeController });
      $routeProvider.when('/about', { templateUrl: '/pages/about.html', controller: AboutController });
      $routeProvider.when('/privacy', { templateUrl: '/pages/privacy.html', controller: AboutController });
      $routeProvider.when('/terms', { templateUrl: '/pages/terms.html', controller: AboutController });
      $routeProvider.otherwise({ redirectTo: '/' });
  }]);

내 앱에는 / pages 디렉토리 내에서 새 html 파일을 복사하고 추가 할 수있는 CMS가 내장되어 있습니다 .

동적으로 추가 된 새 파일에도 여전히 라우팅 공급자를 사용하고 싶습니다.

이상적인 세계에서 라우팅 패턴은 다음과 같습니다.

$ routeProvider.when ( ‘/ pagename ‘, {templateUrl : ‘/ pages / pagename .html’, 컨트롤러 : CMSController});

따라서 새 페이지 이름이 “contact.html”이면 angular가 “/ contact”를 선택하여 “/pages/contact.html”로 리디렉션하고 싶습니다.

이것이 가능할까요?! 그렇다면 어떻게?!

최신 정보

이제 라우팅 구성에 다음이 있습니다.

$routeProvider.when('/page/:name', { templateUrl: '/pages/home.html', controller: CMSController })

내 CMSController에서 :

function CMSController($scope, $route, $routeParams) {
    $route.current.templateUrl = '/pages/' + $routeParams.name + ".html";
    alert($route.current.templateUrl);
}
CMSController.$inject = ['$scope', '$route', '$routeParams'];

그러면 현재 templateUrl이 올바른 값으로 설정됩니다.

그러나 이제 새 templateUrl 값으로 ng-view 를 변경하고 싶습니다 . 이것은 어떻게 이루어 집니까?



답변

angular.module('myapp', ['myapp.filters', 'myapp.services', 'myapp.directives']).
        config(['$routeProvider', function($routeProvider) {
        $routeProvider.when('/page/:name*', {
            templateUrl: function(urlattr){
                return '/pages/' + urlattr.name + '.html';
            },
            controller: 'CMSController'
        });
    }
]);
  • *를 추가하면 여러 수준의 디렉토리에서 동적으로 작업 할 수 있습니다 . 예 : / page / cars / selling / list 는이 제공 업체에서 포착됩니다.

문서 (1.3.0)에서 :

“templateUrl이 함수 인 경우 다음 매개 변수를 사용하여 호출됩니다.

{Array.}-현재 경로를 적용하여 현재 $ location.path ()에서 추출한 경로 매개 변수 “

또한

when (path, route) : 방법

  • 경로는 콜론으로 시작하고 별표로 끝나는 명명 된 그룹을 포함 할 수 있습니다 (예 : 이름 *). 모든 문자는 경로가 일치 할 때 주어진 이름으로 $ routeParams에 열심히 저장됩니다.


답변

좋아, 해결했다.

GitHub에 솔루션 추가-http : //gregorypratt.github.com/AngularDynamicRouting

내 app.js 라우팅 구성에서 :

$routeProvider.when('/pages/:name', {
    templateUrl: '/pages/home.html',
    controller: CMSController
});

그런 다음 내 CMS 컨트롤러에서 :

function CMSController($scope, $route, $routeParams) {

    $route.current.templateUrl = '/pages/' + $routeParams.name + ".html";

    $.get($route.current.templateUrl, function (data) {
        $scope.$apply(function () {
            $('#views').html($compile(data)($scope));
        });
    });
    ...
}
CMSController.$inject = ['$scope', '$route', '$routeParams'];

#views가 내 <div id="views" ng-view></div>

이제 표준 라우팅 및 동적 라우팅과 함께 작동합니다.

그것을 테스트하기 위해 나는 그것을 Portfolio.html이라고 부르는 about.html을 복사하고 그것의 내용 중 일부를 변경 /#/pages/portfolio하고 내 브라우저에 입력 했고 hey presto Portfolio.html이 표시되었습니다 ….

업데이트
$ apply 및 $ compile을 html에 추가하여 동적 콘텐츠를 삽입 할 수 있습니다.


답변

그런 일을하는 가장 쉬운 방법은 나중에 경로를 해결하는 것이라고 생각합니다. 예를 들어 json을 통해 경로를 요청할 수 있습니다. 구성 단계에서 $ provide를 통해 $ routeProvider에서 팩토리를 만들어 실행 단계와 컨트롤러에서도 $ routeProvider 개체를 계속 사용할 수 있는지 확인합니다.

'use strict';

angular.module('myapp', []).config(function($provide, $routeProvider) {
    $provide.factory('$routeProvider', function () {
        return $routeProvider;
    });
}).run(function($routeProvider, $http) {
    $routeProvider.when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
    }).otherwise({
        redirectTo: '/'
    });

    $http.get('/dynamic-routes.json').success(function(data) {
        $routeProvider.when('/', {
            templateUrl: 'views/main.html',
            controller: 'MainCtrl'
        });
        // you might need to call $route.reload() if the route changed
        $route.reload();
    });
});


답변

$ routeProvider URI 패턴에서 다음과 같이 변수 매개 변수를 지정 $routeProvider.when('/page/:pageNumber' ...하고 $ routeParams를 통해 컨트롤러에서 액세스 할 수 있습니다.

$ route 페이지 끝에 좋은 예가 있습니다 : http://docs.angularjs.org/api/ng.$route

편집 (편집 된 질문의 경우) :

라우팅 시스템은 안타깝게도 매우 제한적입니다.이 주제에 대해 많은 논의가 있으며, 여러 개의 명명 된 뷰 생성 등을 통해 일부 솔루션이 제안되었습니다. 그러나 현재 ngView 지시문은 경로당 하나의 뷰만 제공합니다. 일대일 기준. 여러 가지 방법으로이 작업을 수행 할 수 있습니다. 더 간단한 방법은 뷰의 템플릿을 <ng-include src="myTemplateUrl"></ng-include>태그가 있는 로더로 사용하는 것입니다 ($ scope.myTemplateUrl이 컨트롤러에서 생성됨).

나는 기본적으로 $ route 서비스를 완전히 건너 뛰는 더 복잡한 (그러나 더 크고 더 복잡한 문제의 경우 더 깨끗한) 솔루션을 사용합니다.

http://www.bennadel.com/blog/2420-Mapping-AngularJS-Routes-Onto-URL-Parameters-And-Client-Side-Events.htm


답변

이것이 왜 작동하는지 확실하지 않지만 angular 1.2.0-rc.2에서 동적 (또는 선호하는 경우 와일드 카드) 경로가 가능합니다.

http://code.angularjs.org/1.2.0-rc.2/angular.min.js
http://code.angularjs.org/1.2.0-rc.2/angular-route.min.js

angular.module('yadda', [
  'ngRoute'
]).

config(function ($routeProvider, $locationProvider) {
  $routeProvider.
    when('/:a', {
  template: '<div ng-include="templateUrl">Loading...</div>',
  controller: 'DynamicController'
}).


controller('DynamicController', function ($scope, $routeParams) {
console.log($routeParams);
$scope.templateUrl = 'partials/' + $routeParams.a;
}).

example.com/foo-> “foo”부분로드

example.com/bar-> “bar”부분로드

ng-view에서 조정할 필요가 없습니다. ‘/ : a’케이스는 이것을 달성 할 수있는 유일한 변수입니다. ‘/ : foo’는 부분이 모두 foo1, foo2 등이 아니면 작동하지 않습니다. ‘/ : a’는 모든 부분과 함께 작동합니다. 이름.

모든 값은 동적 컨트롤러를 실행하므로 “otherwise”는 없지만 동적 또는 와일드 카드 라우팅 시나리오에서 찾고있는 것이라 생각합니다.


답변

AngularJS 1.1.3부터는 새로운 catch-all 매개 변수를 사용하여 원하는 작업을 정확하게 수행 할 수 있습니다.

https://github.com/angular/angular.js/commit/7eafbb98c64c0dc079d7d3ec589f1270b7f6fea5

커밋에서 :

따라서 routeProvider는 콜론 대신 별표가 접두사로 붙은 경우 슬래시가 포함 된 경우에도 하위 문자열과 일치하는 매개 변수를 허용 할 수 있습니다. 예를 들어, 같은 경로는 이와 같은 것과 edit/color/:color/largecode/*largecode
일치합니다
http://appdomain.com/edit/color/brown/largecode/code/with/slashs.

나는 (1.1.5 사용) 직접 테스트했으며 훌륭하게 작동합니다. 각 새 URL은 컨트롤러를 다시로드하므로 모든 종류의 상태를 유지하려면 사용자 지정 서비스를 사용해야 할 수 있습니다.


답변

다음은 잘 작동하는 또 다른 솔루션입니다.

(function() {
    'use strict';

    angular.module('cms').config(route);
    route.$inject = ['$routeProvider'];

    function route($routeProvider) {

        $routeProvider
            .when('/:section', {
                templateUrl: buildPath
            })
            .when('/:section/:page', {
                templateUrl: buildPath
            })
            .when('/:section/:page/:task', {
                templateUrl: buildPath
            });



    }

    function buildPath(path) {

        var layout = 'layout';

        angular.forEach(path, function(value) {

            value = value.charAt(0).toUpperCase() + value.substring(1);
            layout += value;

        });

        layout += '.tpl';

        return 'client/app/layouts/' + layout;

    }

})();