Задать вопрос
Ответы пользователя по тегу Angular
  • Как получить данные конкретного элемента на странице?

    Bowen
    @Bowen Автор вопроса
    Японский бог
    Можно еще так:
    import { Directive, Output, ElementRef, EventEmitter,  ContentChildren } from '@angular/core';
    import { NavigationEnd, Router, RouterLinkActive, RouterLinkWithHref } from '@angular/router';
    import { Subscription } from 'rxjs';
    
    @Directive({
      selector: '[routerLink]'
    })
    
    export class ActiveRouteDirective {
      @ContentChildren(RouterLinkWithHref, { descendants: true }) linksWithHrefs;
    
      @Output('isActiveRouteEmitter') isActiveEmitter: EventEmitter<any> = new EventEmitter<any>();
    
      private subscription: Subscription;
    
      constructor(
        private router: Router, 
        private element: ElementRef
      ) {
        this.router = router;
        this.element = element;
        this.subscription = router.events.subscribe(s => {
            if (s instanceof NavigationEnd) {
              this.update();
            }
        });
      }
    
      ngAfterContentInit() {
        this.linksWithHrefs.changes.subscribe(() => this.update());
        this.update();
      }
    
      ngOnDestroy() {
        this.subscription.unsubscribe();
      }
    
      update() {
        if (!this.linksWithHrefs || !this.router.navigated) return;
        const isActive = this.linksWithHrefs.some(link => this.router.isActive(link.urlTree, true));
        if (isActive) {
          this.isActiveEmitter.emit(this.element.nativeElement);
        }
      }
    }

    HTML код
    <div class="menu__item" #rla="routerLinkActive" routerLinkActive="menu__item--active" [routerLinkActiveOptions]="{ exact: true }" *ngFor="let item of menu">
        <a (isActiveRouteEmitter)="getParams($event)" routerLink="/{{ item.link }}" [ngClass]="{'menu__link': true, 'menu__link--active': rla.isActive}">
            {{ item.name }}
        </a>
    </div>

    Добавляем метод getParams в компонент
    getParams($target){
      console.log($target.getBoundingClientRect());
    }


    Ссылка с рабочим примером
    Ответ написан
    Комментировать
  • Позволяет ли Angular 2 выполнять валидацию параметров маршрута на уровне роутинга?

    Bowen
    @Bowen Автор вопроса
    Японский бог
    Решил таким образом:
    1. Создал сервис в котором у меня осуществляется проверка параметров маршрутов.
    2. Импортировал этот сервис в главном модуле app.module
    3. Прописал его в providers
    router-params.guard.ts
    import { Injectable } from '@angular/core';
    import { CanActivate , ActivatedRouteSnapshot } from '@angular/router';
    import { map, every } from 'lodash';
    
    /**
     * Список параметров
     * Сам список можете вынести в отдельном файле(я же для теста указал тут)
     * @type {Object}
     */
    const gp = {
    	action: 'add|edit',
    	id: '[0-9]'
    };
    
    @Injectable()
    export class RouterGuard implements CanActivate {
    	canActivate(route: ActivatedRouteSnapshot) {
    		let access: Array<boolean> = [];
    		map(route.params, (v: any, k: any) => access.push(new RegExp(gp[k], 'g').test(v)));
    		return every(access, Boolean);
    	}
    };


    app.module.ts
    import RouterParamsGuard from './router-params.guard';
    @NgModule({
      imports: [
        BrowserModule,
        HttpModule,
        AppRoutingModule
      ],
      declarations: [
        AppComponent,
        HomeComponent,
        NotFoundComponent
      ],
      providers: [{
          provide: APP_BASE_HREF,
          useValue: '/'
        }, {
          provide: LocationStrategy,
          useClass: PathLocationStrategy
        },
        {
          provide: 'RouterParamsGuard',
          useClass: RouterParamsGuard
        },
        AppStore
      ],
      bootstrap: [
        AppComponent
      ]
    })

    Теперь в файлах где у меня были прописаны маршруты, к нужному маршруту добавил:
    canActivate: ['RouterParamsGuard']

    Выглядит это так
    export const routes: Routes = [{
        path: 'post/:id',
        loadChildren: './post?chunkName=post',
        canActivate: ['RouterParamsGuard']
    }];

    Реализовать наверное можно было и по другому, но я так и не понял как это можно было сделать.
    Ответ написан
    Комментировать