programing

Angular가 있는 자동 다이내믹 브레드 크럼 만드는 방법JS + 각도 UI 라우터

muds 2023. 3. 22. 22:18
반응형

Angular가 있는 자동 다이내믹 브레드 크럼 만드는 방법JS + 각도 UI 라우터

웹 애플리케이션의 주요 컴포넌트 중 하나는 브레드 크럼/내비게이션입니다.Angular UI 라우터에서는 컨트롤러가 아닌 개별 상태에 브레드 크럼 메타데이터를 넣는 것이 좋습니다.필요한 각 컨트롤러에 대해 수동으로 Breadcrumbs 객체를 작성하는 것은 간단한 작업이지만 매우 복잡한 작업이기도 합니다.

Angular와 함께 자동 빵가루에 대한 몇 가지 솔루션을 본 적이 있지만, 솔직히 말해서, 그것들은 다소 원시적입니다.대화 상자나 측면 패널과 같은 일부 상태에서는 브레드 크럼이 업데이트되지 않아야 하지만 앵귤러에 대한 현재 추가 정보에서는 이를 표현할 방법이 없습니다.

또 다른 문제는 빵가루의 제목이 정적이지 않다는 것이다.예를 들어 [사용자 상세(User Detail)]페이지로 이동하는 경우, 브레드 크럼의 제목은 일반적인 "사용자 상세(User Detail)"가 아니라 사용자의 전체 이름이어야 합니다.

마지막으로 해결해야 할 문제는 부모 링크에 대해 올바른 상태 파라미터 값을 모두 사용하는 것입니다.들어 '사용할 수 없다'라는 '사용할 수 없다'가 합니다.:companyId.

이 정도 수준의 빵가루 지지대를 제공하는 앵글 추가물이 있나요?그렇지 않다면 어떻게 하면 좋을까요?컨트롤러를 복잡하게 하고 싶지 않습니다.대부분의 컨트롤러가 필요하기 때문에 가능한 한 자동화되어 번거롭지 않게 하고 싶습니다.

감사합니다!

예전에 제가 직접 해결한 적이 있어요. 왜냐하면 구할 수 있는 게 아무것도 없었기 때문이죠.는 이 말을 .data반대합니다. 왜냐하면 우리는 사실 우리의 빵 부스러기 타이틀이 아이들에게 상속되는 것을 원하지 않기 때문입니다.경우에 따라서는, 모달 다이얼로그와 오른쪽 패널이 슬라이드 되어 기술적으로는 「자녀 뷰」가 되는 경우가 있습니다만, 브레드 크럼에는 영향을 주지 않습니다.「」를 사용해 .breadcrumb오브젝트 대신 자동 상속을 피할 수 있습니다.

의 「 」의 titleproperty를 하고 $interpolate다른 장소에서 해결할 필요 없이 브레드클럼 데이터와 해결 범위를 조합할 수 있습니다.어느 경우든 해결 범위를 사용하고 싶었기 때문에 이 방법은 매우 효과적입니다.

제 솔루션에서는 i18n도 취급하고 있습니다.

$stateProvider
    .state('courses', {
        url: '/courses',
        template: Templates.viewsContainer(),
        controller: function(Translation) {
            Translation.load('courses');
        },
        breadcrumb: {
            title: 'COURSES.TITLE'
        }
    })
    .state('courses.list', {
        url: "/list",
        templateUrl: 'app/courses/courses.list.html',
        resolve: {
            coursesData: function(Model) {
                return Model.getAll('/courses');
            }
        },
        controller: 'CoursesController'
    })
    // this child is just a slide-out view to add/edit the selected course.
    // It should not add to the breadcrumb - it's technically the same screen.
    .state('courses.list.edit', {
        url: "/:courseId/edit",
        templateUrl: 'app/courses/courses.list.edit.html',
        resolve: {
            course: function(Model, $stateParams) {
                return Model.getOne("/courses", $stateParams.courseId);
            }
        },
        controller: 'CourseFormController'
    })
    // this is a brand new screen, so it should change the breadcrumb
    .state('courses.detail', {
        url: '/:courseId',
        templateUrl: 'app/courses/courses.detail.html',
        controller: 'CourseDetailController',
        resolve: {
            course: function(Model, $stateParams) {
                return Model.getOne('/courses', $stateParams.courseId);
            }
        },
        breadcrumb: {
            title: '{{course.name}}'
        }
    })
    // lots more screens.

지령에 따라 빵가루를 묶고 싶지 않았습니다. 왜냐하면 제 어플리케이션에서 빵가루를 시각적으로 보여주는 방법이 여러 가지가 있을 것 같았기 때문입니다.그래서 서비스에 넣었습니다.

.factory("Breadcrumbs", function($state, $translate, $interpolate) {
    var list = [], title;

    function getProperty(object, path) {
        function index(obj, i) {
            return obj[i];
        }

        return path.split('.').reduce(index, object);
    }

    function addBreadcrumb(title, state) {
        list.push({
            title: title,
            state: state
        });
    }

    function generateBreadcrumbs(state) {
        if(angular.isDefined(state.parent)) {
            generateBreadcrumbs(state.parent);
        }

        if(angular.isDefined(state.breadcrumb)) {
            if(angular.isDefined(state.breadcrumb.title)) {
                addBreadcrumb($interpolate(state.breadcrumb.title)(state.locals.globals), state.name);
            }
        }
    }

    function appendTitle(translation, index) {
        var title = translation;

        if(index < list.length - 1) {
            title += ' > ';
        }

        return title;
    }

    function generateTitle() {
        title = '';

        angular.forEach(list, function(breadcrumb, index) {
            $translate(breadcrumb.title).then(
                function(translation) {
                    title += appendTitle(translation, index);
                }, function(translation) {
                    title += appendTitle(translation, index);
                }
            );
        });
    }

    return {
        generate: function() {
            list = [];

            generateBreadcrumbs($state.$current);
            generateTitle();
        },

        title: function() {
            return title;
        },

        list: function() {
            return list;
        }
    };
})

그 후, 실제의 브레드 크럼 디렉티브는 매우 심플하게 됩니다.

.directive("breadcrumbs", function() {
    return {
        restrict: 'E',
        replace: true,
        priority: 100,
        templateUrl: 'common/directives/breadcrumbs/breadcrumbs.html'
    };
});

템플릿:

<h2 translate-cloak>
    <ul class="breadcrumbs">
        <li ng-repeat="breadcrumb in Breadcrumbs.list()">
            <a ng-if="breadcrumb.state && !$last" ui-sref="{{breadcrumb.state}}">{{breadcrumb.title | translate}}</a>
            <span class="active" ng-show="$last">{{breadcrumb.title | translate}}</span>
            <span ng-hide="$last" class="divider"></span>
        </li>
    </ul>
</h2>

여기 스크린샷에서 두 내비게이션 모두에서 완벽하게 작동하는 것을 볼 수 있습니다.

여기에 이미지 설명 입력

html "html"도 있습니다.<title> 삭제:

여기에 이미지 설명 입력

PS to Angular UI Team : 이런 것을 바로 추가해주세요!

이에 대한 제 해결책을 공유하고 싶습니다., 이름 있는 크럼 라벨을 하며, 사용법을 사용할 수 .rumb"을 사용할 수 있습니다.resolve:기능을 사용하여 브레드 크럼 이름을 지정합니다.

상태 설정 예:

$stateProvider
    .state('home', {
        url: '/',
        ...
        data: {
            displayName: 'Home'
        }
    })
    .state('home.usersList', {
        url: 'users/',
        ...
        data: {
            displayName: 'Users'
        }
    })
    .state('home.userList.detail', {
        url: ':id',
        ...
        data: {
            displayName: '{{ user.name | uppercase }}'
        }
        resolve: {
            user : function($stateParams, userService) {
                return userService.getUser($stateParams.id);
            }
        }
    })

다음으로 디렉티브 속성으로 브레드크럼라벨(displayname)의 위치를 지정해야 합니다.

<ui-breadcrumbs displayname-property="data.displayName"></ui-breadcrumbs>

는, 「Directive」의 값을 을 인식합니다.$state.$current.data.displayName사용할 텍스트를 찾습니다.

$cramable 빵 부스러기 이름

상태 「」 「」 「」)에 주의해 주세요.home.userList.detail인 Angular 구문 displayName 을 {{ value }}. 하면 에 된 모든 할 수 resolve오브젝트를 지정합니다.통상, 이것은, 유저명의 상기의 예와 같이, 서버로부터 데이터를 취득하기 위해서 사용됩니다.이것은 정규 Angular 문자열이므로 필터를 적용하는 위의 예시와 같이 displayName 필드에 유효한 Angular 식을 포함할 수 있습니다.

데모

다음은 Plunker에 관한 데모를 보여드리겠습니다.http://plnkr.co/edit/bBgdxgB91Z6323HLWCzF?p=preview

코드

여기에 모든 코드를 넣는 것은 조금 무리라고 생각했기 때문에, GitHub에 게재되어 있습니다.https://github.com/michaelbromley/angularUtils/tree/master/src/directives/uiBreadcrumbs

저는 ui-router의 상태에 따라 브레드 크럼을 생성하는 Angular 모듈을 만들었습니다.말씀하신 모든 기능이 포함되어 있습니다(최근에 이 투고를 읽고 있는 동안 브레드 크럼 내의 상태를 무시할 수 있는 가능성을 추가했습니다).

여기 github repo가 있습니다.

컨트롤러 스코프에 대해 보간된 동적 라벨(네스트된 뷰/복수 뷰의 경우 "가장 깊은" 라벨)을 사용할 수 있습니다.

상태 체인은 상태 옵션에 따라 사용자 지정할 수 있습니다(API 참조 참조).

모듈에는 미리 정의된 템플릿이 포함되어 있으며 사용자 정의 템플릿을 사용할 수 있습니다.

기능이 내장되어 있다고는 생각하지 않습니다만, 모든 툴이 준비되어 있습니다.Location Provider를 봐 주세요.단순히 네비게이션 요소가 이 기능을 사용하고, 그 밖에 알고 싶은 것이 있으면 삽입하기만 하면 됩니다.

문서

ui-router의 내부를 깊이 들여다본 결과, 해결된 자원을 사용하여 어떻게 브레드 크럼을 만들 수 있는지 알게 되었습니다.

여기 내 지시에 대한 단서가 있다.

메모: 이 코드가 플런커 내에서 올바르게 동작하도록 할 수 없었습니다만, 지시는 제 프로젝트내에서 동작합니다.routes.breadcrumb의 제목을 설정하는 방법의 예로서만 제공됩니다.

@egervari에서 제공하는 솔루션에 감사드립니다.$stateParams 속성을 브레드 크럼의 커스텀 데이터에 추가해야 하는 사용자용.키 'title' 값에 대한 구문 {:id}을(를) 확장했습니다.

.state('courses.detail', {
    url: '/:courseId',
    templateUrl: 'app/courses/courses.detail.html',
    controller: 'CourseDetailController',
    resolve: {
        course: function(Model, $stateParams) {
            return Model.getOne('/courses', $stateParams.courseId);
        }
    },
    breadcrumb: {
        title: 'course {:courseId}'
    }
})

다음은 Plunker의 예입니다.참고하세요.

언급URL : https://stackoverflow.com/questions/21970406/how-to-make-automated-dynamic-breadcrumbs-with-angularjs-angular-ui-router

반응형