কিভাবে কৌণিক একটি রুট পরিবর্তন সনাক্ত করতে?


426

আমি আমার মধ্যে একটি রুট পরিবর্তন সনাক্ত করতে চাই AppComponent

তারপরে আমি গ্লোবাল ব্যবহারকারীর টোকেনটি পরীক্ষা করে দেখব যে তিনি লগ ইন করেছেন কিনা Then

উত্তর:


534

কৌনিক 2 এ আপনি subscribeএকটি রাউটার উদাহরণে (আরএক্স ইভেন্ট) করতে পারেন । সুতরাং আপনি যেমন জিনিস করতে পারেন

class MyClass {
  constructor(private router: Router) {
    router.subscribe((val) => /*whatever*/)
  }
}

সম্পাদনা করুন (আরসি 1 থেকে)

class MyClass {
  constructor(private router: Router) {
    router.changes.subscribe((val) => /*whatever*/)
  }
}

2 সম্পাদনা করুন (২.০.০ থেকে)

আরও দেখুন: রাউটার.এভেন্টস ডক

class MyClass {
  constructor(private router: Router) {
    router.events.subscribe((val) => {
        // see also 
        console.log(val instanceof NavigationEnd) 
    });
  }
}

2
আমি event._root.children[0].value._routeConfig.dataআশা করি আরও ভাল উপায় হতে পারে আশা করে আমি ডেটা পেতে সক্ষম হচ্ছি
অক্ষয়

6
@ অক্ষয় আপনি এই নিবন্ধটি টড মোটো দ্বারা দেখেছেন: [রাউটার ইভেন্ট সহ কৌনিক 2 তে ডায়নামিক পৃষ্ঠার শিরোনাম] ( toddmotto.com/dynamic-page-titles-angular-2-router-events )
বোগাক

9
কেন এটি 3 বার আগুন লাগে?
টুলকিট

2
@ টুলকিট কারণ এটি ইভেন্টটির 3 টি রাজ্য রয়েছে এবং ইউআরএলটির সফল সাফল্য রয়েছে। 3 টি রাজ্য হ'ল: 'নেভিগেশনস্টার্ট', 'নেভিগেশনএন্ড' এবং 'রুটস রিকগনিটেড'
রিকার্ডো গঞ্জেলস

10
আপনি আরএক্সজেএস filterঅপারেটরের সাথে ইভেন্টগুলি সহজেই ফিল্টার করতে পারবেন । router.events.pipe(filter(e => e instanceof NavigationEnd).subscribe((e) => { ... }
সাইমন_উইভার

313

আরএক্সজেএস 6

router.events.pipe(filter(event => event instanceof NavigationStart))

পিলোনরেজকে ধন্যবাদ (নীচে মন্তব্য দেখুন)

নতুন রাউটার> = আরসি ৩

import { Router, NavigationStart, NavigationEnd, NavigationError, NavigationCancel, RoutesRecognized } from '@angular/router';

constructor(router:Router) {
  router.events.forEach((event) => {
    if(event instanceof NavigationStart) {
    }
    // NavigationEnd
    // NavigationCancel
    // NavigationError
    // RoutesRecognized
  });
}

আপনি প্রদত্ত ইভেন্টের মাধ্যমেও ফিল্টার করতে পারেন:

import 'rxjs/add/operator/filter';

constructor(router:Router) {
  router.events
    .filter(event => event instanceof NavigationStart)
    .subscribe((event:NavigationStart) => {
      // You only receive NavigationStart events
    });
}

পূর্ববর্তী এবং বর্তমান ইভেন্টটি পেতে pairwiseঅপারেটরটি ব্যবহার করাও একটি দুর্দান্ত ধারণা। https://github.com/angular/angular/issues/11268#issuecomment-244601977

import 'rxjs/add/operator/pairwise';
import { Router } from '@angular/router;

export class AppComponent {
    constructor(private router: Router) {
        this.router.events.pairwise().subscribe((event) => {
            console.log(event);
        });
    };
}

1
পছন্দ করুন এবং 'ইভেন্ট: ইভেন্ট' প্রথম বন্ধনীতে হওয়া উচিত। এর জন্য ধন্যবাদ, বেশ শক্তিশালী নতুন বৈশিষ্ট্য! আমি এটি পছন্দ করি
ম্যাক্সিম

2
এটি বর্তমান সংস্করণগুলিতে একটি সংকলন ত্রুটি ফেলে দেয়Argument of type '(event: Event) => void' is not assignable to parameter of type
রুডি স্ট্রিডোম

1
@ রূডিস্ট্রিডম এবং গন্টার জ্যাচবাউয়ার - Argument of type '(event: Event) => void' is not assignable to parameter of typeত্রুটিটি হ'ল কারণ আপনার ফিল্টার স্নিপেটে আপনি নেভিগেশনএভেন্টের পরিবর্তে ইভেন্ট টাইপের কোনও অবজেক্টের সাবস্ক্রাইব করছেন।
Bonnici

1
দ্বিতীয় নমুনা ইভেন্টের পরিবর্তে নেভিগেশন ইভেন্ট হওয়া উচিত। @ কৌনিক / রাউটার থেকে "নেভিগেশন ইভেন্ট হিসাবে ইভেন্ট" আমদানি করতে ভুলবেন না
মিক 21

1
আমদানি সম্পর্কে ইঙ্গিতটি এই ত্রুটিটি সমাধান করতে চাইছেন সবার জন্য :)
মিক

91

জন্য কৌণিক 7 কেউ মত লেখা উচিত:

this.router.events.subscribe((event: Event) => {})


একটি বিস্তারিত উদাহরণ নিম্নরূপ হতে পারে:

import { Component } from '@angular/core'; 
import { Router, Event, NavigationStart, NavigationEnd, NavigationError } from '@angular/router';

@Component({
    selector: 'app-root',
    template: `<router-outlet></router-outlet>`
})
export class AppComponent {

    constructor(private router: Router) {

        this.router.events.subscribe((event: Event) => {
            if (event instanceof NavigationStart) {
                // Show loading indicator
            }

            if (event instanceof NavigationEnd) {
                // Hide loading indicator
            }

            if (event instanceof NavigationError) {
                // Hide loading indicator

                // Present error to user
                console.log(event.error);
            }
        });

   }
}

2
এটা অসাধারণ! খুব ব্যাপক! কৌণিক on. এ পুরোপুরি কাজ করেছে
মায়লারটেলর

1
আপনি প্রিলোডিং কৌশলটি ব্যবহার করেন সাধারণত ন্যাভিগেশন নিজেই খুব কম সময় নেয়। ব্যবহারের ক্ষেত্রে আমি কেবলমাত্র ব্যাকএন্ড এইচটিপি অনুরোধগুলিতে লোডিং সূচকগুলি ব্যবহার করব।
ফিল

5
ইন কন্সট্রাকটর , আপনি ব্যবহার করা উচিত নয় <এই>, আপনার ক্ষেত্রে ngOnInit জন্য।
সেরজিও রেইস

1
নিখুঁত, আমি কীভাবে url এর সঠিক প্যারাম.আইডি পেতে পারি?
শিবিনরাগ

2
সমাধান উপাদান সীমাবদ্ধ নয়, এটি অ্যাপ্লিকেশন জুড়ে ছড়িয়ে পড়ে, সম্পদ গ্রহণ করে
মোঃ রফি

54

কৌণিক 7 , আপনি করতে চান তাহলে subscribeকরতেrouter

import { Router, NavigationEnd } from '@angular/router';

import { filter } from 'rxjs/operators';

constructor(
  private router: Router
) {
  router.events.pipe(
    filter(event => event instanceof NavigationEnd)  
  ).subscribe((event: NavigationEnd) => {
    console.log(event.url);
  });
}

2
এটি পুনর্নির্দেশ ইভেন্টটি ক্যাপচার করে না
আনন্দহু অজাইকুমার

40

কৌণিক 4.x এবং উপরে:

এটি নীচের মতো অ্যাক্টিভেটেড রুট শ্রেণির url সম্পত্তি ব্যবহার করে অর্জন করা যেতে পারে ,

this.activatedRoute.url.subscribe(url =>{
     console.log(url);
});

দ্রষ্টব্য: আপনার angular/routerপ্যাকেজ থেকে সরবরাহকারীটি আমদানি এবং ইনজেক্ট করতে হবে

import { ActivatedRoute } from '@angular/router`

এবং

constructor(private activatedRoute : ActivatedRoute){  }


16

কৌণিক 6 এবং আরএক্সজেএস 6 এ:

import { filter, debounceTime } from 'rxjs/operators';

 this.router.events.pipe(
      filter((event) => event instanceof NavigationEnd),
      debounceTime(40000)
    ).subscribe(
      x => {
      console.log('val',x);
      this.router.navigate(['/']); /*Redirect to Home*/
}
)

3
আপনি রাউটারের জন্য আমদানি মিস করেছেনimport {Router, NavigationEnd} from "@angular/router"
দামির বেইলখানভ

15

উত্তর এখানে জন্য সঠিক router-deprecated। এর সর্বশেষ সংস্করণটির জন্য router:

this.router.changes.forEach(() => {
    // Do whatever in here
});

অথবা

this.router.changes.subscribe(() => {
     // Do whatever in here
});

দুজনের মধ্যে পার্থক্যটি দেখতে, দয়া করে এই এসও প্রশ্নটি দেখুন

সম্পাদন করা

সর্বশেষের জন্য আপনাকে অবশ্যই:

this.router.events.subscribe(event: Event => {
    // Handle route change
});

এটি পূর্ববর্তী এবং বর্তমান রুটের কোনও ডেটা সরবরাহ করে?
আকান

routerআবার আপডেট করা হয়েছে (আমি আমার উত্তর এখনও আপডেট হয়েছে), তাই আমি নিশ্চিত কিভাবে এটা সর্বশেষ জন্য নই। জন্য routerআমি নিয়ে লিখেছেন, আপনি না। @akn
দেহলি

দয়া করে আপনি এই উত্তরের জন্য কিছু প্রসঙ্গ সরবরাহ করতে পারেন? আপনার সাথে অন্যান্য সমাধানগুলিতে কোন লাইনগুলি প্রতিস্থাপন করছেন?
জেরার্ড সিম্পসন

12

কৌনিক 8 এ আপনার পছন্দ করা উচিত this.router.events.subscribe((event: Event) => {})

উদাহরণ:

import { Component } from '@angular/core'; 
import { Router, Event } from '@angular/router';
import { NavigationStart, NavigationError, NavigationEnd } from '@angular/router';

@Component({
    selector: 'app-root',
    template: `<router-outlet></router-outlet>`
})
export class AppComponent {

    constructor(private router: Router) {
        //Router subscriber
        this.router.events.subscribe((event: Event) => {
            if (event instanceof NavigationStart) {
                //do something on start activity
            }

            if (event instanceof NavigationError) {
                // Handle error
                console.error(event.error);
            }

            if (event instanceof NavigationEnd) {
                //do something on end activity
            }
        });
   }
}

10

উপাদানটিতে, আপনি এটি চেষ্টা করতে পারেন:

import {NavigationEnd, NavigationStart, Router} from '@angular/router';

constructor(private router: Router) {
router.events.subscribe(
        (event) => {
            if (event instanceof NavigationStart)
                // start loading pages
            if (event instanceof NavigationEnd) {
                // end of loading paegs
            }
        });
}

8

নিম্নলিখিত পদ্ধতিতে রুট পরিবর্তন ইভেন্টগুলি ক্যাপচার করুন ...

import { Component, OnInit, Output, ViewChild } from "@angular/core";
import { Router, NavigationStart, NavigationEnd, Event as NavigationEvent } from '@angular/router';

@Component({
    selector: "my-app",
    templateUrl: "app/app.component.html",
    styleUrls: ["app/app.component.css"]
})
export class AppComponent {

    constructor(private cacheComponentObj: CacheComponent,
        private router: Router) {

        /*  Route event types
            NavigationEnd
            NavigationCancel
            NavigationError
            RoutesRecognized
        */
        router.events.forEach((event: NavigationEvent) => {

            //Before Navigation
            if (event instanceof NavigationStart) {
                switch (event.url) {
                case "/app/home":
                {
                    //Do Work
                    break;
                }
                case "/app/About":
                {
                    //Do Work
                    break;
                }
                }
            }

            //After Navigation
            if (event instanceof NavigationEnd) {
                switch (event.url) {
                case "/app/home":
                {
                    //Do Work
                    break;
                }
                case "/app/About":
                {
                    //Do Work
                    break;
                }
                }
            }
        });
    }
}

নিখুঁত, আমি কীভাবে url এর সঠিক প্যারাম.আইডি পেতে পারি?
শিবিনরাগ

6

অবস্থান কাজ করে ...

import {Component, OnInit} from '@angular/core';
import {Location} from '@angular/common';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})

export class AppComponent implements OnInit {

    constructor(private location: Location) {
        this.location.onUrlChange(x => this.urlChange(x));
    }

    ngOnInit(): void {}

    urlChange(x) {
        console.log(x);
    }
}

চমৎকার উত্তর. এটা আমার ক্ষেত্রে কাজ করে। ধন্যবাদ
উমর তারিক

4

বেশিরভাগ সমাধানগুলির উপরে সঠিক, তবে আমি এই এমিটটি একাধিকবার 'নেভিগেশন এমিট' ইভেন্টের মুখোমুখি করছি w সুতরাং শুনুন কৌণিক 6 এর সম্পূর্ণ সমাধান।

import { Subscription } from 'rxjs/Subscription';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/filter';    

export class FooComponent implements OnInit, OnDestroy {
   private _routerSub = Subscription.EMPTY;
   constructor(private router: Router){}

   ngOnInit(){
     this._routerSub = this.router.events
      .filter(event => event instanceof NavigationEnd)
      .subscribe((value) => {
         //do something with the value
     });
  }

  ngOnDestroy(){
   this._routerSub.unsubscribe();
  }
} 

3

@ লুডোহেন উত্তরটি দুর্দান্ত, তবে আপনি যদি instanceofনিম্নলিখিতটি ব্যবহার করতে না চান তবে

this.router.events.subscribe(event => {
  if(event.constructor.name === "NavigationStart") {
    // do something...
  }
});

এই পদ্ধতিতে আপনি বর্তমান ইভেন্টের নামটি স্ট্রিং হিসাবে পরীক্ষা করতে পারেন এবং যদি ইভেন্টটি ঘটে থাকে তবে আপনি নিজের ফাংশনটি করার জন্য যা পরিকল্পনা করেছিলেন তা করতে পারেন।


3
টাইপ স্ক্রিপ্ট সুরক্ষা কেন ব্যবহার করবেন না?
পাসকাল

@ প্যাসাল কেন ঘৃণা? এবং এ Eventধরণের কারণে এটিম একটি ত্রুটি ঘটায় যে কারণে আমি এটি ব্যবহার করিনি
খালেদ আল-আনসারী

2
@ পাসল না এটি একটি কৌণিক সমস্যা যেহেতু রাউটার ইভেন্টটি ব্রাউজার ইভেন্টের মতো নয় এবং সে কারণেই ইভেন্টের ধরণটি কার্যকর হবে না! তাদের এই ইভেন্টের জন্য একটি নতুন ইন্টারফেস তৈরি করা দরকার, আমার বলা উচিত ছিল শুরু থেকেই কিন্তু অযৌক্তিক নিচে ভোট কার্যকর হয়নি :)
খালেদ আল-আনসারী

5
যেহেতু সংশোধন উত্পাদন কোডে সঞ্চালিত হয় instanceOfআপনার বরং ব্যবহার করা উচিত যাতে আপনার উদাহরণটি উত্পাদন কোডেও কাজ করবে। if(event instanceOf NavigationStart) {
মিলান জারিক

1
হওয়া উচিতif(event instanceof NavigationStart)
কেতন

1

আমি কৌনিক 5 অ্যাপ্লিকেশন নিয়ে কাজ করছি এবং আমি একই সমস্যার মুখোমুখি হচ্ছি। যখন আমি কৌনিক ডকুমেন্টেশন দিয়ে যাই তারা রাউটার ইভেন্টগুলি পরিচালনা করার জন্য সর্বোত্তম সমাধান সরবরাহ করে following

কোনও নেভিগেশন সফলভাবে শেষ হলে ট্রিগার হওয়া ইভেন্টটির প্রতিনিধিত্ব করে

এটি কিভাবে ব্যবহার করবেন?

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRouteSnapshot, NavigationEnd } from '@angular/router';
@Component({
    selector: 'app-navbar',
    templateUrl: './navbar.component.html',
    styleUrls: ['./navbar.component.css']
})
export class NavbarComponent implements OnInit {
    constructor(private router: Router) { }
    ngOnInit(): void {
        //calls this method when navigation ends
        this.router.events.subscribe(event => {
            if (event instanceof NavigationEnd) {
                //calls this stuff when navigation ends
                console.log("Event generated");
            }
        });
    }
}

কখন এটি ব্যবহার করবেন?

আমার ক্ষেত্রে আমার অ্যাপ্লিকেশনটি ব্যবহারকারীর, অ্যাডমিনদের মতো সমস্ত ব্যবহারকারীর জন্য সাধারণ ড্যাশবোর্ড শেয়ার করে তবে ব্যবহারকারীর ধরণ অনুসারে আমাকে কিছু নভবার অপশন দেখানো এবং আড়াল করা দরকার।

এই কারণেই যখনই ইউআরএল পরিবর্তন হয় তখন আমাকে পরিষেবা পদ্ধতিতে কল করতে হবে যা প্রতিক্রিয়া অনুসারে ব্যবহারকারীর তথ্যে লগইন করে যে আমি আরও ক্রিয়াকলাপে যাব।


0

নিম্নলিখিত ধরণের কাজ করে এবং আপনার জন্য কৌতূহলপূর্ণ হতে পারে।

// in constructor of your app.ts with router and auth services injected
router.subscribe(path => {
    if (!authService.isAuthorised(path)) //whatever your auth service needs
        router.navigate(['/Login']);
    });

দুর্ভাগ্যক্রমে এই রাউটিং প্রক্রিয়াটি আমার পছন্দের চেয়ে পরে পুনর্নির্দেশ করে। onActivate()মূল লক্ষ্য উপাদানের পুনর্নির্দেশ আগে বলা হয়।

@CanActivateআপনি লক্ষ্য উপাদানটিতে ব্যবহার করতে পারেন এমন একটি ডেকোরেটর রয়েছে তবে এটি ক) কেন্দ্রীভূত নয় এবং খ) ইনজেকশন পরিষেবাদি থেকে উপকৃত হয় না।

কেউ যদি কোনও রুট প্রতিশ্রুতিবদ্ধ হওয়ার আগে কেন্দ্রীয়ভাবে অনুমোদনের আরও ভাল উপায়ের পরামর্শ দিতে পারে তবে তা দুর্দান্ত হবে। আমি নিশ্চিত আরও ভাল উপায় থাকতে হবে।

এটি আমার বর্তমান কোড (রুট পরিবর্তন শোনার জন্য আমি কীভাবে এটি পরিবর্তন করব?):

import {Component, View, bootstrap, bind, provide} from 'angular2/angular2';
import {ROUTER_BINDINGS, RouterOutlet, RouteConfig, RouterLink, ROUTER_PROVIDERS, APP_BASE_HREF} from 'angular2/router';    
import {Location, LocationStrategy, HashLocationStrategy} from 'angular2/router';

import { Todo } from './components/todo/todo';
import { About } from './components/about/about';

@Component({
    selector: 'app'
})

@View({
    template: `
        <div class="container">
            <nav>
                <ul>
                    <li><a [router-link]="['/Home']">Todo</a></li>
                    <li><a [router-link]="['/About']">About</a></li>
                </ul>
            </nav>
            <router-outlet></router-outlet>
        </div>
    `,
    directives: [RouterOutlet, RouterLink]
})

@RouteConfig([
    { path: '/', redirectTo: '/home' },
    { path: '/home', component: Todo, as: 'Home' },
    { path: '/about', component: About, as: 'About' }
])

class AppComponent {    
    constructor(location: Location){
        location.go('/');
    }    
}    
bootstrap(AppComponent, [ROUTER_PROVIDERS, provide(APP_BASE_HREF, {useValue: '/'})]);

আমি দেখেছি লোকেরা রাউটারআউটলেটকে প্রসারিত করে তাদের লেখক কোড যুক্ত করতে যা একটি উপায়। এটি সম্পর্কে গিটহাবের সাথে কথা আছে তবে এখনও কোন উপসংহার পাওয়া যায়নি .. এখানে অথ0 এর উপায়: auth0.com/blog/2015/05/14/…
ডেনিস স্মোকল

আপনার প্রতিক্রিয়ার জন্য আপনাকে ধন্যবাদ. কৌণিক 2 এর জন্য authService শেখার জন্য কোনও ভাল ভিডিও জানেন?
AngularM

0

আরসি 5 সাল থেকে আমি এটি এটি করি

this.router.events
  .map( event => event instanceof NavigationStart )
  .subscribe( () => {
    // TODO
  } );

0

পছন্দ মতো অ্যাপরআউটিংমডুলিতে কেবল পরিবর্তন করুন

@NgModule({
imports: [RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled' })],
  exports: [RouterModule]
})

0

কৌণিক 8. বর্তমান রুটটি বেস রুট কিনা তা পরীক্ষা করুন

  baseroute: boolean;
  constructor(
    private router: Router,
  ) {
    router.events.subscribe((val: any) => {
      if (val.url == "/") {
        this.baseroute = true;
      } else {
        this.baseroute = false;
      }
    });
  }

0

আমি এই জাতীয় কিছু লিখতে হবে:

ngOnInit() {
this.routed = this.router.events.map( event => event instanceof NavigationStart )
  .subscribe(() => {
  } );
}

ngOnDestroy() {
this.routed.unsubscribe();
}

-3

কৌণিক ৮. এর সহজ উত্তর

constructor(private route:ActivatedRoute) {
  console.log(route);
}

1
এটি কি কেবলমাত্র ইনস্ট্যান্টেশনে কার্যকর করা হয় না, তা হবে: কেবল একবার !? এটি কোনও সমাধান নয়।
Satria
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.