【问题标题】:How do you pass a parent components input value to two child components using the Router module in Angular 4?如何使用 Angular 4 中的 Router 模块将父组件输入值传递给两个子组件?
【发布时间】:2017-10-04 02:02:05
【问题描述】:

所以,我正在创建一个基本的 Airbnb 搜索。我有 3 个组件: SearchComponent,其中包括搜索表单; ListingComponent,列出了Airbnb的租金;和 MapComponent,它在谷歌地图上显示每个租赁所在的标记。 SearchComponent 是 ListingComponent 和 MapComponent 的父组件,我使用 Router 模块在两个子组件之间导航。为了让两个子组件在列表或地图中显示租金,它们需要在 SearchComponent 中输入表单的输入值。如何将此值传递给两个子组件?

search.component.html

我希望这个 locationSearch 输入值通过 <router-outlet></router-outlet> 传递给我的两个子组件。

<form class="mui-form">
    <div class="mui-textfield mui-textfield--float-label">
        <input type="text" name="locationSearch" [(ngModel)]="locationSearch" (keyup)="searchLocation()">
        <label>Location</label>
    </div>
</form>

<router-outlet></router-outlet>

search.component.ts

import { Component, OnInit } from '@angular/core';
import { SearchService } from "app/search.service";

@Component({
  selector: 'app-search',
  templateUrl: './search.component.html',
  styleUrls: ['./search.component.scss']
})
export class SearchComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

更新 - 似乎仍然无法正常工作

由于某种原因,我的 list.component.ts 中的 location 属性在我更改搜索时没有更新。

路线

const appRoutes: Routes = [
    { path: '', component: SearchComponent, children: [
        { path: '', redirectTo: 'listing', pathMatch: 'full' },
        { path: 'listing', component: ListingComponent },
        { path: 'map', component: MapComponent }
    ]},
    { path: 'detail/:id', component: ListingDetailComponent },
];

search.service.ts

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

@Injectable()
export class SearchService {
    private _inputValue = new BehaviorSubject('Starting Value');
    inputValue$ = this._inputValue.asObservable();

    updateSearch(search: string) {
        this._inputValue.next(search);
    }
}

search.component.ts

该组件中的位置值正在更新,但list.component.ts中没有更新

import { Component, OnInit, OnDestroy } from '@angular/core';
import { SearchService } from "app/search.service";
import { Subscription }   from 'rxjs/Subscription';

@Component({
    selector: 'app-search',
    templateUrl: './search.component.html',
    styleUrls: ['./search.component.scss'],
    providers: [ SearchService ]
})
export class SearchComponent implements OnInit {
    locationSearch: string;
    location: string = 'None';

    constructor(private searchService: SearchService) {
        this.searchService.inputValue$.subscribe(res => this.location = res); // This location value is updating
    }

    ngOnInit() {}

    updateInput() {
        this.searchService.updateSearch(this.locationSearch);
    }
}

list.component.ts

import { Component, Input, OnInit, OnDestroy } from '@angular/core';
import { AirbnbService } from "app/airbnb.service";
import { SearchService } from "app/search.service";
import { Subscription }   from 'rxjs/Subscription';

@Component({
  selector: 'app-listing',
  templateUrl: './listing.component.html',
  styleUrls: ['./listing.component.scss'],
  providers: [ SearchService ]
})
export class ListingComponent implements OnInit {
    listings;
    location: string = 'None';

    constructor(private airbnb: AirbnbService, private searchService: SearchService) {
        this.searchService.inputValue$.subscribe(res => this.location = res);

        // Output rentals
        this.airbnb.getByLocation().subscribe(res => {
            console.log(res.search_results);
            this.listings = res.search_results; // this listings property isn't updating for some reason.
        });
    }

    ngOnInit() {}
}

Image of what is happening

【问题讨论】:

  • 使用angular.io/docs/ts/latest/cookbook/…中解释的共享服务
  • @GünterZöchbauer 我想我对如何在服务中访问 SearchComponent 的输入字段值感到困惑......一旦我弄清楚了,我会很高兴的。
  • 组件应将其传递给服务。服务不应主动访问组件。
  • 哦,好的。我明白了!谢谢
  • 嘿@GünterZöchbauer,你能再看看我的代码吗?出于某种原因,我在list.component.ts 中的位置属性在我更改搜索时没有更新。不太清楚是什么问题。

标签: angular angular2-routing angular2-services angular2-directives


【解决方案1】:

我刚刚做了一些非常相似的事情(成功地),我很确定您只是提供了 SearchService 太多次。您的代码正在创建 SearchService 的两个实例,因此它们具有不同的值。

你需要一个单例,所以只写一次providers: [ SearchService ]。这将是所有组件的最高父级(我认为是 search.component.ts)。

尝试修改你的孩子:

import { Component, Input, OnInit, OnDestroy } from '@angular/core';
import { AirbnbService } from "app/airbnb.service";
import { SearchService } from "app/search.service";
import { Subscription }   from 'rxjs/Subscription';

@Component({
  selector: 'app-listing',
  templateUrl: './listing.component.html',
  styleUrls: ['./listing.component.scss']//,
  //providers: [ SearchService ] // REMOVE THIS LINE

})
export class ListingComponent implements OnInit {
    listings;
    location: string = 'None';

    constructor(private airbnb: AirbnbService, private searchService: SearchService) {
        this.searchService.inputValue$.subscribe(res => this.location = res);

        // Output rentals
        this.airbnb.getByLocation().subscribe(res => {
            console.log(res.search_results);
            this.listings = res.search_results; // this listings property isn't updating for some reason.
        });
    }

    ngOnInit() {}
}

【讨论】:

    猜你喜欢
    • 2021-09-20
    • 2017-05-29
    • 2018-08-20
    • 1970-01-01
    • 1970-01-01
    • 2018-08-11
    • 1970-01-01
    • 2020-02-04
    • 2021-03-21
    相关资源
    最近更新 更多