कोणीय 2: मूल घटक से मार्गपार्म्स प्राप्त करना


79

मैं मूल घटक से मार्गप्रदर्श कैसे प्राप्त करूं?

App.ts:

@Component({
  ...
})

@RouteConfig([
  {path: '/', component: HomeComponent, as: 'Home'},
  {path: '/:username/...', component: ParentComponent, as: 'Parent'}
])

export class HomeComponent {
  ...
}

और फिर, में ParentComponent, मैं आसानी से अपना उपयोगकर्ता नाम परम प्राप्त कर सकता हूं और बाल मार्ग निर्धारित कर सकता हूं।

Parent.ts:

@Component({
  ...
})

@RouteConfig([
  { path: '/child-1', component: ChildOneComponent, as: 'ChildOne' },
  { path: '/child-2', component: ChildTwoComponent, as: 'ChildTwo' }
])

export class ParentComponent {

  public username: string;

  constructor(
    public params: RouteParams
  ) {
    this.username = params.get('username');
  }

  ...
}

लेकिन फिर, मैं उन बाल घटकों में यह 'उपयोगकर्ता नाम' पैरामीटर कैसे प्राप्त कर सकता हूं? ऊपर के रूप में एक ही चाल करना, यह नहीं करता है। क्योंकि उन params को ProfileComponent या कुछ और पर परिभाषित किया गया है ??

@Component({
  ...
})

export class ChildOneComponent {

  public username: string;

  constructor(
    public params: RouteParams
  ) {
    this.username = params.get('username');
    // returns null
  }

  ...
}

बच्चों पर एक इनपुट संपत्ति के बारे में कैसे? जैसे, माता-पिता के खाके में:<child-one-component [username]="username"> ...
मार्क राजकोक

क्या यह भी काम करेगा <routerlink [username]="username">...? और क्या तब @MarkRajcok जाने का रास्ता?
ऐको क्लेन ओविंक

मुझे लगता है कि आप पूछ रहे हैं कि क्या कुछ <a [router-link]="[ './....', {username: username} ]काम करेगा। क्षमा करें, मुझे नहीं पता कि यह काम करेगा या नहीं। (मैंने अभी तक रूटिंग के साथ नहीं खेला है।)
मार्क राजकोक

मुझे क्षमा करें @MarkRajcok, मैंने इसे गलत लिखा है .. मेरा मतलब है <router-outlet></router-outlet>, क्या मुझे उस पर इनपुट डालना चाहिए। क्योंकि बाल मार्ग वहाँ रेंडर करता है ..
ऐको क्लेन ओविंक

2
उपयोगी जानकारी हो सकती है github.com/angular/angular/issues/6204#issuecomment-173273143
Günter Zöchbauer

जवाबों:


72

अपडेट करें:

अब जब आधिकारिक रूप से Angular2 फाइनल जारी किया गया था, तो ऐसा करने का सही तरीका निम्नलिखित है:

export class ChildComponent {

    private sub: any;

    private parentRouteId: number;

    constructor(private route: ActivatedRoute) { }

    ngOnInit() {
        this.sub = this.route.parent.params.subscribe(params => {
            this.parentRouteId = +params["id"];
        });
    }

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

मूल:

यहाँ है कि मैंने इसे "@ कोणीय / राउटर" का उपयोग करके कैसे किया: "3.0.0-alp.6" पैकेज:

export class ChildComponent {

    private sub: any;

    private parentRouteId: number;

    constructor(
        private router: Router,
        private route: ActivatedRoute) {
    }

    ngOnInit() {
        this.sub = this.router.routerState.parent(this.route).params.subscribe(params => {
            this.parentRouteId = +params["id"];
        });
    }

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

इस उदाहरण में मार्ग का निम्न प्रारूप है: / माता-पिता /: आईडी / बच्चा /: बच्चा

export const routes: RouterConfig = [
    {
        path: '/parent/:id',
        component: ParentComponent,
        children: [
            { path: '/child/:childid', component: ChildComponent }]
    }
];

2
आपको इसे ngOnInit में कॉल करने की आवश्यकता है (जैसा कि दिखाया गया है) कंस्ट्रक्टर में नहीं है क्योंकि मैंने पहले मूर्खतापूर्ण प्रयास किया था।
कैमरून

2
एंगुलर 5.2 के बाद से एक वैकल्पिक तरीका है जिससे आपको parent1+ बार पार करने की आवश्यकता नहीं है । देखें stackoverflow.com/a/48511516/4185989 फिर भी विचार कर रहा लायक subscribe/ unsubscribeहालांकि, इस उत्तर से पैटर्न।
jmq

कोणीय 6 मेंthis.activatedRoute.parent.snapshot.params.someParam
तस्नीम रेजा

@Jmq द्वारा बताया गया समाधान कोणीय 6 के लिए सबसे अच्छा है, साथ ही, हमें मूल आईडी के लिए अलग से सदस्यता लेने की आवश्यकता नहीं है।
सीखना ...

सही समाधान! खरीदें कि मुझे माता-पिता के परमेस प्राप्त करने के लिए सदस्यता लेने की आवश्यकता क्यों है? परम तो पहले से ही है! :: सोच ::
moreirapontocom

10

आपको RouteParamsअपने में उपयोग करने का प्रयास नहीं करना चाहिए ChildOneComponent

RouteRegistryइसके बजाय, का उपयोग करें !

@Component({
  ...
})

export class ChildOneComponent {

  public username: string;

  constructor(registry: RouteRegistry, location: Location) {
    route_registry.recognize(location.path(), []).then((instruction) => {
      console.log(instruction.component.params['username']);
    })
  }


  ...
}

अद्यतन: इस पुल अनुरोध के रूप में (कोणीय Beta.9): https://github.com/angular/angular/pull/7163

अब आप बिना वर्तमान निर्देश तक पहुँच सकते हैं recognize(location.path(), [])

उदाहरण:

@Component({
  ...
})

export class ChildOneComponent {

  public username: string;

  constructor(_router: Router) {
    let instruction = _router.currentInstruction();
    this.username = instruction.component.params['username'];
  }

  ...
}

मैंने अभी तक इसकी कोशिश नहीं की है

अधिक जानकारी यहाँ:

https://github.com/angular/angular/blob/master/CHANGELOG.md#200-beta9-2016-03-09 https://angular.io/docs/ts/latest/api/router/Router-class .html

अद्यतन 2: कोणीय 2.0.0.beta15 से एक छोटा सा परिवर्तन:

अब currentInstructionकोई फंक्शन नहीं है। इसके अलावा, आपको rootराउटर को लोड करना होगा । (रिपोर्टिंग के लिए @ Lxrd-AJ को धन्यवाद)

@Component({
  ...
})

export class ChildOneComponent {

  public username: string;

  constructor(_router: Router) {
    let instruction = _router.root.currentInstruction;
    this.username = instruction.component.params['username'];
  }

  ...
}

क्या यह बाल मार्गों के लिए किया जाना चाहिए? मैं इस मुद्दे पर भी चल रहा हूँ जहाँ बाल मार्गों को माता-पिता के घटकों के रूटपरैम नहीं देख सकते हैं। उदाहरण के लिए मार्ग / उपयोगकर्ता /: user_id / पोस्ट /: post_id, मैं पोस्ट घटक से user_id नहीं प्राप्त कर सकता हूँ .... यह मेरे लिए Hacky लगता है कि मेरे पास RouteRegistry का उपयोग करना है।
mharris7190

@ mharris7190 मैंने अपना उत्तर अपडेट किया। कोणीय बीटा 9 से शुरू करके आप सीधे राउटर घटक से वर्तमान निर्देश प्राप्त कर सकते हैं।
ProGM

अद्यतन के लिए धन्यवाद। मैं Beta.6 से बीटा.13 में अपग्रेड करने वाला हूं, इसलिए मैं इसे करने के बाद इसे आजमाऊंगा।
mharris7190

3
इस उत्तर के लिए एक मामूली संपादित करें, का उपयोग करें _router.root.currentInstruction.component.params['id']रूट पर जोर दें क्योंकि अब आपको रूट राउटर से करंट इंप्रेशन मिलता है और नहीं _router। पुनश्च: मैं उपयोग कर रहा हूँangular2.0.0-beta.15
Lxrd-AJ

_router.root अब मौजूद नहीं है। (मैं Angular 2.4.7 का उपयोग करता हूं)
Eivind Gussiås Løkseth

7

जैसा कि गुंटर ज़ोचौएर ने उल्लेख किया है, मैंने अपनी समस्या के समाधान के लिए https://github.com/angular/angular/issues/6204#issuecomment-173273143 पर टिप्पणी का उपयोग किया । मैंने Injectorकक्षा का उपयोग angular2/coreमाता-पिता के रनरपैम को लाने के लिए किया। कोणीय 2 बाहर मुड़ता है गहरी नेस्टेड मार्गों को नहीं संभालता है। शायद वे भविष्य में इसे जोड़ देंगे।

constructor(private _issueService: IssueService,
            private _injector: Injector) {}

getIssues() {
    let id = this._injector.parent.parent.get(RouteParams).get('id');
    this._issueService.getIssues(id).then(issues => this.issues = issues);
}

8
यह कोणीय 2 आरसी राउटर पर अब काम नहीं करता है।
Inn0vative1

6

मुझे माता-पिता (ठीक दूसरे पूर्वज) इंजेक्टर का अनुरोध करके और प्राप्त करके एक बदसूरत लेकिन काम करने वाला समाधान मिला RouteParams यहां से ।

कुछ इस तरह

@Component({
  ...
})
export class ChildOneComponent {
  public username: string;

  constructor(injector: Injector) {
    let params = injector.parent.parent.get(RouteParams);

    this.username = params.get('username');
  }
}

इसे साझा करने के लिए बहुत-बहुत धन्यवाद, क्या कोणीय टीम द्वारा कोई बगट्रॉकर प्रविष्टि या बयान दिया गया है कि भविष्य में इसे कैसे संभाला जाएगा?
मार्कस रिएमर

लगता है कि
.par

4

RC5 + @ कोणीय / राउटर ":" 3.0.0-rc.1 समाधान: ऐसा लगता है कि this.router.routerState.queryParamsइसे हटा दिया गया है। आप माता-पिता के मार्ग को इस प्रकार प्राप्त कर सकते हैं:

constructor(private activatedRoute: ActivatedRoute) {
}    

this.activatedRoute.parent.params.subscribe(
  (param: any) => {
    let userId = param['userId'];
    console.log(userId);
  });

2

आप इंजेक्टर से चाइल्ड कंपोनेंट के अंदर पेरेंट रूट के कंपोनेंट ले सकते हैं और फिर चाइल्ड कंपोनेंट से कोई भी प्राप्त कर सकते हैं। आप इस तरह से

@Component({
  ...
})

export class ChildOneComponent {

  public username: string;

  constructor(
    public params: RouteParams
    private _injector: Injector

  ) {
    var parentComponent = this._injector.get(ParentComponent)

    this.username = parentComponent.username;
    //or
    this.username = parentComponent.params.get('username');
  }

  ...
}

2

यदि आप अपने कोड के लिए यूनिट परीक्षण लिखना चाहते हैं तो बाल घटक में कंस्ट्रक्टर के लिए इंजेक्टर उदाहरण पास करना अच्छा नहीं हो सकता है।

इसके आसपास काम करने का सबसे आसान तरीका मूल घटक में एक सेवा वर्ग है, जिसमें आप अपने आवश्यक पैरामस को सहेजते हैं।

@Component({
    template: `<div><router-outlet></router-outlet></div>`,
    directives: [RouterOutlet],
    providers: [SomeServiceClass]
})
@RouteConfig([
    {path: "/", name: "IssueList", component: IssueListComponent, useAsDefault: true}
])
class IssueMountComponent {
    constructor(routeParams: RouteParams, someService: SomeServiceClass) {
        someService.id = routeParams.get('id');
    }
}

फिर आप बस उसी सर्विस को चाइल्ड कंपोनेंट में इंजेक्ट करते हैं और परमेस को एक्सेस करते हैं।

@Component({
    template: `some template here`
})
class IssueListComponent implements OnInit {
    issues: Issue[];
    constructor(private someService: SomeServiceClass) {}

    getIssues() {
        let id = this.someService.id;
        // do your magic here
    }

    ngOnInit() {
        this.getIssues();
    }
}

ध्यान दें कि आपको मूल घटक डेकोरेटर में "प्रदाताओं" का उपयोग करके अपने मूल घटक और उसके बच्चे के घटकों के लिए ऐसी सेवा का दायरा करना चाहिए।

मैं इस लेख को DI और स्कैप 2 के बारे में कोणीय 2 में सुझाता हूं: http://blog.thoughtram.io/angular/2015/08/20/host-and-visibility-in-angular-2-d dependency-injection.html


2

RC6 में, राउटर 3.0.0-rc.2 (शायद RC5 में भी काम करता है), आप इस मामले में एक स्नैपशॉट के रूप में URL से रूट पैरामेट्स ले सकते हैं, जो कि इस एक लाइनर के साथ वेधशालाओं के बिना, परमर्स नहीं बदलेगा:

this.route.snapshot.parent.params['username'];

इस तरह के रूप में ActivatedRoute इंजेक्षन करने के लिए मत भूलना:

constructor(private route: ActivatedRoute) {};


2

RxJS के साथ Observable.combineLatest, हम मुहावरेदार पारमों से निपटने के लिए कुछ कर सकते हैं:

import 'rxjs/add/operator/combineLatest';

import {Component} from '@angular/core';
import {ActivatedRoute, Params} from '@angular/router';
import {Observable} from 'rxjs/Observable';

@Component({ /* ... */ })
export class SomeChildComponent {
  email: string;
  id: string;

  constructor(private route: ActivatedRoute) {}

  ngOnInit() {
    Observable.combineLatest(this.route.params, this.route.parent.params)
        .forEach((params: Params[]) => {
          this.id = params[0]['id'];
          this.email = params[1]['email'];
        });
  }
}

1

मैंने Angular 2 rc.1 के लिए इस तरह का हैक लिखना समाप्त कर दिया

import { Router } from '@angular/router-deprecated';
import * as _ from 'lodash';

interface ParameterObject {
  [key: string]: any[];
};

/**
 * Traverse route.parent links until root router and check each level
 * currentInstruction and group parameters to single object.
 *
 * e.g.
 * {
 *   id: [314, 593],
 *   otherParam: [9]
 * }
 */
export default function mergeRouteParams(router: Router): ParameterObject {
  let mergedParameters: ParameterObject = {};
  while (router) {
    let currentInstruction = router.currentInstruction;
    if (currentInstruction) {
      let currentParams = currentInstruction.component.params;
      _.each(currentParams, (value, key) => {
        let valuesForKey = mergedParameters[key] || [];
        valuesForKey.unshift(value);
        mergedParameters[key] = valuesForKey;
      });
    }
    router = router.parent;
  }
  return mergedParameters;
}

अब देखने के बजाय RouteParamsमैं पढ़ने के बजाय मापदंडों को इकट्ठा करता हूं मैं उन्हें केवल राउटर के माध्यम से प्राप्त करता हूं:

@Component({
  ...
})

export class ChildishComponent {

  constructor(router: Router) {
    let allParams = mergeRouteParams(router);
    let parentRouteId = allParams['id'][0];
    let childRouteId = allParams['id'][1];
    let otherRandomParam = allParams.otherRandomParam[0];
  }

  ...
}  

बहुत अच्छा काम करता है! मैंने इस पद्धति को एक MergedRouteParamsवर्ग के अंदर निजी बना दिया getहै जो मानक RouteParamsवर्ग की विधि को लागू करता है (दूसरा पैरामीटर सूचकांक है, शून्य में चूक)।
जिम बक

0

में अंतिम की थोड़ी मदद के साथ RXJS आप (बच्चे और माता पिता से) दोनों नक्शे गठजोड़ कर सकते हैं:

(route) => Observable
    .zip(route.params, route.parent.params)
    .map(data => Object.assign({}, data[0], data[1]))

अन्य प्रश्न एक हो सकते हैं:

  • क्या यह वास्तव में ऊपर उपयोग करने के लिए एक अच्छा विचार है - युग्मन के कारण (माता-पिता के परम के साथ युगल बाल घटक - एपी स्तर पर नहीं - छिपा युग्मन),
  • क्या यह RXJS के कार्यकाल में उचित दृष्टिकोण है (इसके लिए हार्डकोर RXJS उपयोगकर्ता प्रतिक्रिया की आवश्यकता होगी;)

0

आप इसे स्नैपशॉट पर निम्न के साथ कर सकते हैं, लेकिन यदि यह बदल जाता है, तो आपकी idसंपत्ति अपडेट नहीं की जाएगी।

यह उदाहरण यह भी दिखाता है कि आप सभी पूर्वज पैरामीटर परिवर्तनों की सदस्यता कैसे ले सकते हैं और आप जिस पैरामीटर के सभी पर्यवेक्षकों को मर्ज करके अपनी रुचि रखते हैं, उसे देखें। हालांकि, इस पद्धति से सावधान रहें क्योंकि कई पूर्वजों के पास एक ही पैरामीटर कुंजी / नाम हो सकता है।

import { Component } from '@angular/core';
import { ActivatedRoute, Params, ActivatedRouteSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';
import 'rxjs/add/observable/merge';

// This traverses the route, following ancestors, looking for the parameter.
function getParam(route: ActivatedRouteSnapshot, key: string): any {
  if (route != null) {
    let param = route.params[key];
    if (param === undefined) {
      return getParam(route.parent, key);
    } else {
      return param;
    }
  } else {
    return undefined;
  }
}

@Component({ /* ... */ })
export class SomeChildComponent {

  id: string;

  private _parameterSubscription: Subscription;

  constructor(private route: ActivatedRoute) {
  }

  ngOnInit() {
    // There is no need to do this if you subscribe to parameter changes like below.
    this.id = getParam(this.route.snapshot, 'id');

    let paramObservables: Observable<Params>[] =
      this.route.pathFromRoot.map(route => route.params);

    this._parametersSubscription =
      Observable.merge(...paramObservables).subscribe((params: Params) => {
        if ('id' in params) {
          // If there are ancestor routes that have used
          // the same parameter name, they will conflict!
          this.id = params['id'];
        }
      });
  }

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

0

कोणीय 8 में मूल घटक से मार्गपार्म्स प्राप्त करना -

मेरे पास एक मार्ग है http: // localhost: 4200 / साथी / छात्र-प्रोफ़ाइल / 1234 / जानकारी

मूल मार्ग - छात्र-प्रोफ़ाइल

परम - 1234 (student_id)

बाल मार्ग - जानकारी


चाइल्ड रूट (जानकारी) में परम की पहुँच -

आयात

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

निर्माता

constructor(private activatedRoute: ActivatedRoute, private router: Router) { }

अभिभावक मार्ग परिमों तक पहुंचना

this.activatedRoute.parent.paramMap.subscribe((params: ParamMap) => this.studentId = (params.get('student_id')));


अब, हमारे परिवर्तनशील छात्र I का मान है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.