2014-10-01 2 views
1

<ul> 요소에 앉아서 활성화 된 현재 경로를 기준으로 자식 "<li>"에 "활성"클래스를 적용하는 데코레이터를 작성하려고합니다.데코레이터에서 현재 경로를 찾으려면 어떻게합니까?

라우터를 데코레이터에 삽입하여 다음과 같은 작업을 수행 할 수 있습니까?

class ActiveNavDecorator { 

    RouteProvider _router; 
    String _currentRoute; 

    ActiveNavDecorator(this._router) { 
    _currentRoute = _router.currentURLPath() // I am looking for something that will do this 
    } 
} 

는 아무도 내가이 작업을 수행 할 수있는 방법을 알고 있나요?

감사합니다,
· 병

+0

작동하지 않는 기능은 무엇입니까? 너는 그걸 시도하지 않았 니? –

+0

currentURLPath()는 실제 메소드가 아닙니다. 그것은 내가 성취하고자하는 것을 보여주는 것일뿐입니다. –

+0

하지만 RouteProvider 인스턴스가 주입 되었습니까? –

답변

0

다음은이 문제에 대한 내 솔루션입니다.

필자는 몇 달 전에 이것을 조사하여 비슷한 솔루션을 발견했기 때문에 부분적으로 만 활용할 수있었습니다. 그 원래의 해결책을 누가 썼는지, 어디에서 읽었는지 기억이 안납니다. 미리 사과하십시오! 원저자가 이것을보고 의견을 남기면 답변을 속성으로 업데이트합니다.

import 'dart:html'; 

import 'package:angular/angular.dart'; 
import 'package:route_hierarchical/client.dart'; 

/// This decorator modifies UI elements based on the currently selected route. 
/// 
/// For example, when a menu item is clicked, we add an 'active' CSS class 
/// to that element so that the user can see where they are. 
@Decorator(selector: '[current-route]') 
class CurrentRoute { 
    Router router; 
    Element element; 

    /// Constructor. 
    /// 
    /// Takes an HTML [element] to monitor and the application's [router]. The 
    /// element must contain a child <a> element. When the route changes, the 
    /// anchor href's first path component will be compared to the new route's 
    /// first path component. If it matches, the CSS class `active` will be 
    /// added to the element. If the route does not match, then the CSS class 
    /// `active` will be removed. 
    CurrentRoute(Element element, Router router) { 
     this.element = element; 
     this.router = router; 

     toggleActive(window.location.href); 

     router.onRouteStart.listen((e) { 
      toggleActive(e.uri); 
     }); 
    } 

    /// Returns true if the given URI matches the anchor href for this element. 
    bool isRoute(String uri) { 
     Element anchor; 

     if (this.element is AnchorElement) { 
      anchor = this.element; 
     } else { 
      anchor = this.element.querySelector('a'); 
     } 

     String anchorPath = anchor.pathname.split('/')[1]; 
     String routePath = Uri.parse(uri).path.split('/')[1]; 

     return anchorPath == routePath; 
    } 

    /// Set the `active` CSS class on an element when it matches the currently 
    /// selected route. 
    void toggleActive(String uri) { 
     if (isRoute(uri)) { 
      element.classes.add('active'); 
     } else { 
      element.classes.remove('active'); 
     } 
    } 
} 

기본 메커니즘은 새로운 경로가 시작될 때마다, current-route로 장식되어 각 요소가 isRoute() 로직을 실행하는 것입니다, 확인합니다 :

어쨌든, 첫 번째 부분은 장식이다 현재 window.location의 첫 번째 경로 구성 요소가 앵커의 첫 번째 경로 구성 요소 인 href과 같은지 확인하십시오. (예 window.location는/foo는/바/바즈와 앵커의 href/foo이며, 그 다음이 일치합니다.입니다)

가,이 단계를 수행 물론 다른 가능한 방법이 있으며, 필요에 따라 isRoute()을 사용자 정의해야 당신의 유스 케이스를 위해. 방금 사용 사례에 맞게 잘 작동했습니다.

다음으로 Angular 's DI를 CurrentRoute에 등록해야합니다. 그것은 독자를위한 운동으로 남겨 두었습니다. 데코레이터는 active 클래스를 필요로하는 요소에 적용되는

<ul class='nav navbar-nav'> 
    <li current-route> 
    <a href='/foo'>Foo</a> 
    </li> 
    <li current-route> 
    <a href='/bar'>Bar</a> 
    </li> 
    <li current-route> 
    <a href='/baz'>Baz</a> 
    </li> 
</ul> 

참고 :

마지막으로, 여기에 부트 스트랩 스타일의 탐색을 기반으로 그것을 사용하는 마크 업의 예입니다. 장식자는 요소가 자체적으로 앵커가 아닌 경우 해당 요소의 첫 번째 <a> 하위 요소를 검색합니다.

관련 문제