简体   繁体   English

Angular 2通过ngOnInit访问其他路由组件的输入值?

[英]Angular 2 Access input value of a different routed component via ngOnInit?

  1. I have a search bar in app.component.ts that has an input value. 我在app.component.ts中有一个具有输入值的搜索栏。

  2. results.component.ts is embedded with a router-outlet in app.component.html results.component.ts嵌入了一个路由器出口,位于app.component.html

  3. When results.component.ts is the current activated route, the search works fine and so do the results. results.component.ts是当前激活的路由时,搜索工作正常,结果也是如此。

  4. However, if someone clicks on a result, results.component.ts is replaced with a different component view detail.component.ts (it provides them with more information about the result.) 但是,如果有人单击结果, results.component.ts将替换为其他组件视图的detail.component.ts (它为他们提供了有关结果的更多信息。)

  5. On detail.component.ts I have a "back to results" link setup with a routerLink='/' . detail.component.ts我使用routerLink='/'建立了“返回结果”链接设置。 And mind you, the search query is still present in the search bar because that view never gets replaced. 提醒您,搜索查询仍然存在于搜索栏中,因为该视图永远不会被替换。

  6. When this back button is clicked, results.component.ts reloads and fires ngOnInit . 点击该后退按钮, results.component.ts重新加载并触发ngOnInit

The problem : I can't access the value of the search string in app.component.ts from results.component.ts ngOnInit to repopulate the results. 问题 :我无法 results.component.ts ngOnInit访问app.component.ts中的搜索字符串的值来重新填充结果。 I've tried almost everything I can think of. 我已经尝试了几乎所有我能想到的东西。

I already have a service built, but I don't know how to set it up to communicate that value, if that is the solution. 我已经建立了一个服务,但是我不知道如何设置它以传达该价值(如果这是解决方案)。

Updated with code 用代码更新

app.component.html app.component.html

//other html
<input placeholder="What do you want to learn?" name="searchStr" [(ngModel)]="searchStr" (keyup.enter)="searchCourse($event)">

interaction-service.service.ts : interact-service.service.ts

import { Injectable } from '@angular/core';
import { Subject }    from 'rxjs/Subject';


@Injectable()
export class InteractionService {

   // Observable string sources
  private searchStr = new Subject<string>();

  // Observable string streams
  searchStr$ = this.searchStr.asObservable();

  sendString(searchString: string) {
    this.searchStr.next(searchString);
  }

}

app.component.ts : app.component.ts

//other imports
import {InteractionService} from './interaction-service.service';

@Component({ 
  selector: 'my-app',
  templateUrl: 'app.component.html',
  providers: [CourseService, InteractionService]
})

export class AppComponent implements OnInit { 

    searchStr: string;

    constructor(private _courseService: CourseService, private _interactionService: InteractionService, private router: Router) {

    }

    ngOnInit() {

    }

    searchCourse(event) {
        this._interactionService.sendString(event.target.value);
        this.router.navigateByUrl('/');
    }

}

course-listings.component.ts (I referred to this as results above) course-listings.component.ts (我在上面将其称为结果)

// other imports
import {Subscription} from 'rxjs';
import {InteractionService} from '../interaction-service.service';

@Component({
  selector: 'app-course-listings',
  templateUrl: './course-listings.component.html',
  providers: [CourseService],
})

export class CourseListingsComponent implements OnInit {

    //some other properties defined
    @Input() searchStr: string;
    subscription: Subscription;

    constructor(private _courseService: CourseService, private _interactionService: InteractionService) {

         this.subscription = this._interactionService.searchStr$.subscribe(
    courses => {
             this.searchStr = courses;

             // code for returning results here..

         }
  );

    }

    ngOnInit() {

    }


}

Your right that you want to use a service. 您想使用服务的权利。 Services are singletons so setting in one component and getting from another will return the passed value. 服务是单例,因此设置一个组件并从另一个组件获取将返回传递的值。

To get a service to work you need to create the service then add it to your app module. 要使服务正常工作,您需要先创建服务,然后将其添加到您的应用模块中。 Then in the constructor for your component you add it so the dependency injection can add it to the component for you. 然后在组件的构造函数中添加它,以便依赖项注入可以将其添加到您的组件中。 The constructor looks like this. 构造函数如下所示。

constructor( private router: Router){}

Each component should have a reference in its constructor and the service singleton is shared. 每个组件在其构造函数中都应该有一个引用,并且服务单例是共享的。

interaction-service.service.ts: interact-service.service.ts:

import { Injectable } from '@angular/core';
import { Subject }    from 'rxjs/Subject';


@Injectable()
export class InteractionService {
    sharedString = "";
}

app.component.ts: app.component.ts:

import {InteractionService} from './interaction-service.service';

@Component({ 
  selector: 'my-app',
  templateUrl: 'app.component.html',
  providers: [CourseService, InteractionService]
})

export class AppComponent implements OnInit { 

constructor(private _courseService: CourseService, private     _interactionService: InteractionService, private router: Router) {

    }

ngOnInit() {
    this.__interactionService.sharedString = "Some value";
}

searchCourse(event) {
    this._interactionService.sendString(event.target.value);
    this.router.navigateByUrl('/');
}

}

I'm going to leave the rest of the code out. 我将其余的代码省去。 The above example should be enough. 上面的例子就足够了。 Simply make the injected interaction service available and set and get the values at will. 只需使注入的交互服务可用并随意设置和获取值即可。 The service values will persist until there is a browser context change. 服务值将持续存在,直到浏览器上下文发生更改。 Last thing I want to mention is when routing call the router like this 我最后要提的是路由选择时,像这样呼叫路由器

this.router.navigate(["url", someParam]);

this will preserve context and not cause a browser context switch when moving between components. 这将保留上下文,并且在组件之间移动时不会导致浏览器上下文切换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM