【问题标题】:Angular 6 Search bar and Result two different non-related componentsAngular 6搜索栏和结果两个不同的不相关组件
【发布时间】:2020-02-16 14:04:01
【问题描述】:

我有两个组件 1. Header Component 2. Result Component 在标题中,我有一个带有单击按钮的搜索栏,我希望将结果填充到结果页面上。

第二个问题是一旦我是结果页面,如果我在标题组件搜索中输入搜索值,它不应该重新加载页面

标头和结果组件都不相关,所以我可以使用@inputoutput 纠正我是否有办法传递值?

ma​​in.component.html

  <app-header *ngIf="auth.isLoggednIn()"></app-header>
  <router-outlet></router-outlet>
  <app-footer></app-footer>
</div>

Header.component.html

    <div class="container">
      <ul>
        <li routerLinkActive="active"><a routerLink="/statupdate">Status Update</a></li>
        <li routerLinkActive="active"><a routerLink="/add">Add New</a></li>
        <li routerLinkActive="active"><a routerLink="/projects">Opportunity</a></li>
      </ul>
      <form class="form-inline" [formGroup]="searchForm" (ngSubmit)="onSubmit()">
        <input class="form-control mr-sm-2" type="search" placeholder="ClientName" aria-label="Search"
          formControlName="searchText">
        <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
      </form>
    </div>
  </div>

Header.component.ts

    this.router.navigate(['search'], {
      queryParams: {
        search: this.searchForm.value.searchText,
      }
    });
  }

我将搜索框中的所有结果都显示在结果页面上,因此我使用路由器进行导航。 结果组件.ts

constructor(private route: ActivatedRoute,public projectService: ProjectService) { }

    ngOnInit() {

        this.projectService.list(this.route.snapshot.queryParamMap.get('search')).subscribe(
          (resp) => {
            this.list = resp;
          },(err) => {
            console.log(err);
          }
        )
    }

是否可以在不重新加载页面的情况下填充数据?我找不到这样的例子

更新我已经编写了 BehaviorSubject 服务来解决这个问题

private messageSource = new BehaviorSubject(<any>[]);
  currentMessage = this.messageSource.asObservable();

  constructor(public httpClient: HttpService) { }

  changeMessage(message) {

    this.httpClient.get('project?clientName=' + message)
      .subscribe(
        (resp) => {
          this.messageSource.next(resp);
        }
      )
  }

但想知道如果可能的话,我是否可以像这样改进这种编码

changeMessage(message) {

    let temp = this.httpClient.get('project?clientName=' + message)
     this.messageSource.next(temp);
  }

我的Result.component.ts

ngOnInit() {
    this.searchService.currentMessage.subscribe(
      (message) => { console.log(message); this.message = message }, (err) => { console.log(err) })
  }

【问题讨论】:

    标签: angular rest search


    【解决方案1】:

    不相关的组件:与服务共享数据

    在缺少直接连接的组件之间传递数据时,例如兄弟姐妹、孙辈等,您应该使用共享服务。当您有应该同步的数据时,我发现 RxJS BehaviorSubject 在这种情况下非常有用。

    您也可以使用常规 RxJS 主题通过服务共享数据,但这就是我更喜欢 BehaviorSubject 的原因。

    1. 它将始终返回订阅时的当前值 - 无需 接电话
    2. 它有一个 getValue() 函数来提取最后一个值作为原始数据。
    3. 它确保组件始终接收最新数据。

    在服务中,我们创建一个私有的 BehaviorSubject 来保存消息的当前值。我们定义了一个 currentMessage 变量,将这个数据流作为一个 observable 来处理,供组件使用。最后,我们创建函数,调用 BehaviorSubject 上的 next 来更改其值。

    父组件、子组件和兄弟组件都接受相同的处理。我们在构造函数中注入 DataService,然后订阅 currentMessage observable 并将其值设置为等于 message 变量。

    现在,如果我们在其中任何一个组件中创建一个函数来更改消息的值。执行此函数时,新数据会自动广播到所有其他组件。

    data.service.ts
    ------------------------
    
    import { Injectable } from '@angular/core';
    import { BehaviorSubject } from 'rxjs';
    
    @Injectable()
    export class DataService {
    
      private messageSource = new BehaviorSubject('default message');
      currentMessage = this.messageSource.asObservable();
    
      constructor() { }
    
      changeMessage(message: string) {
        this.messageSource.next(message)
      }
    
    }
    
    one.component.ts
    -----------------------------
    
    import { Component, OnInit } from '@angular/core';
    import { DataService } from "../data.service";
    
    @Component({
      selector: 'app-parent',
      template: `
        {{message}}
      `,
      styleUrls: ['./sibling.component.css']
    })
    export class ParentComponent implements OnInit {
    
      message:string;
    
      constructor(private data: DataService) { }
    
      ngOnInit() {
        this.data.currentMessage.subscribe(message => this.message = message)
      }
    
    }
    
    
    two.component.ts
    --------------------------------------------
    import { Component, OnInit } from '@angular/core';
    import { DataService } from "../data.service";
    
    @Component({
      selector: 'app-sibling',
      template: `
        {{message}}
        <button (click)="newMessage()">New Message</button>
      `,
      styleUrls: ['./sibling.component.css']
    })
    export class SiblingComponent implements OnInit {
    
      message:string;
    
      constructor(private data: DataService) { }
    
      ngOnInit() {
        this.data.currentMessage.subscribe(message => this.message = message)
      }
    
      newMessage() {
        this.data.changeMessage("Hello from Sibling")
      }
    
    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-26
      • 2020-07-19
      • 2021-01-25
      • 2023-03-25
      • 2018-12-27
      • 1970-01-01
      • 2015-10-10
      • 2023-03-17
      相关资源
      最近更新 更多