【问题标题】:How to pass data from parent to child more than once如何多次将数据从父母传递给孩子
【发布时间】:2016-09-19 19:44:31
【问题描述】:

我正在构建一个 Angular 2 应用程序,其搜索表单和结果显示在同一页面上。我已经使用路由来显示结果部分。所以父组件是具有多个字段的搜索表单,子组件从后端获取结果并显示它。

由于搜索条件涉及多个字段,我通过共享服务将搜索条件传达给子组件。

父组件:

 @Component({
       templateUrl : 'app/search-form.template.html'
    })
    export class SearchFormComponent {

         constructor(private  searchService : SearchService,
                private router: Router){}

         submitSearch(){
          this.searchService.setSearchCriteria(this.model);
          this.router.navigate(['search-form/search-result']);
      }

子组件:

 @Component({
         templateUrl: 'app/search-result/search-result.template.html'
    })
    export class SearchResultComponent implements OnInit{
        private searchResult = [] ;
        constructor(private searchService: SearchService) { }

         ngOnInit() {
                this.searchService.getSearchResult().subscribe(data => {
              this.searchResult = data;
          });

    }

这里是服务代码:

 @Injectable()
    export class SearchService{
       constructor (private http: Http) {}

    setSearchCriteria(searchCriteria : SearchCriteria){
      this.searchCriteria = searchCriteria;
    }

    getSearchResult() : Observable<any> {
        let body = JSON.stringify(this.searchCriteria);
        let headers = new Headers({'content-type' : 'application/json'});
        let options = new RequestOptions({headers : headers});
        return this.http.post(this.baseUrl , body, options)
            .map((res: Response) => res.json().root || {});
    }

使用路由加载父级和子级。这是路由详情

 const appRoutes : Routes = [
      {
        path: '',
        redirectTo: '/search-form',
        pathMatch: 'full'
    },
    {
        path: 'search-form', component: SearchFormComponent,
        children: [
            { path: ''},
            { path: 'search-result', component: SearchResultComponent }
        ]
        }
      ];

main.html 看起来像这样。此处搜索表单(父级)呈现为“搜索表单”

    <nav class="navbar" >
        <div class="container-fluid">
            <router-outlet></router-outlet>
        </div>
      </nav>

search-form.template.html sn-p

  

      <form #searchForm="ngForm" class="form-horizontal"    (ngSubmit)="submitSearch()">
         <!-- form fields -->
         <button type="submit" class="btn btn-sm btn-primary pull-right">Submit</button>
    
        <div class="panel panel-primary">
           <!-- Search Result here -->
            <router-outlet></router-outlet>
        </div>

parent 的 submitSearch() 方法在从 parent 提交表单时被调用。它导航到子组件并显示 searchResult。到目前为止,它工作正常。

我想要的是用户应该能够更改屏幕上的搜索条件并再次点击提交按钮。调用 submitSearch() 方法,但子组件中的结果未更新。我认为根本原因是子组件在 ngOnInit 方法中调用服务。显示结果后,因为我在同一页面上,重新点击提交按钮不会再次创建子组件,因此不会刷新数据。

如何在从父组件提交时使用新的 searchResult 重新加载子组件。

【问题讨论】:

  • 添加了更多细节以显示导航

标签: angular angular2-routing


【解决方案1】:

目前尚不清楚您是如何将其连接起来的。您说SearchResultComponentSearchFormComponent 的子对象,但是您在运行setSearchCriteria 后导航到它,就好像它自己的组件在哪里一样。由于我们看不到模板,因此很难理解发生了什么。

我通常会做这样的事情的方式是在你 setSearchCriteria() 之后在父级中运行 getSearchResult() 并将结果传递给 @Input 中的子级。如果您正在使用诸如 ActivatedRoute 服务之类的东西导航父级,则将子代码从ngOnInit 移动到ngOnChanges,当输入更改时它将被刷新。

【讨论】:

  • 感谢您的回复,我在问题中添加了更多详细信息。我还希望使用子组件中的 @Input 字段将数据传递给子组件。但是,我不确定父母如何将该信息传递给孩子,因为数据绑定不会使用 完成?如果这是微不足道的,请原谅我的无知。
  • 好的,我稍微改变了我的代码。我没有使用路由器,而是根据结果显示/隐藏结果部分。在提交搜索条件时,我调用服务来获取结果并使用@Input 将其传递给子组件。它现在工作:) 感谢您的帮助。接受你的回答
【解决方案2】:

您应该在SearchService 中添加一个Subject。称之为currentResult。一个主题就像一个双向可观察对象,它既是生产者又是消费者。所以在父端你可以是生产者,子端是消费者。

您可能不想在 onInit 中设置搜索条件,但是当父级中发生某些操作时。然后你可以为孩子产生一些价值,这将是倾听。

可能是这样的

从 'rxjs/Subject 导入 { Subject };

@Injectable()
class SearchService {
  private currentSearch = new Subject<any>();

  searchAndSetCurrent(criteria) {
    this.http.get(..).toPromise().then(result => {
      currentSearch.next(result);
    });
  }

  getCurrentSearch(): Observable<any> {
    // asObservable is not really necessary as you can subscribe
    // to a subject. But to make sure people calling this method
    // don't try to emit anything, we should just limit it
    // to the capabilities of an Observable
    return this.currentSearch.asObservable();
  }
}

现在家长可以拨打searchAndSetCurrent,孩子可以订阅。每当父母调用搜索时,当结果进来时,孩子就会得到它。

如果你想对父级中的结果做一些事情,你可以让搜索方法返回一个承诺

searchAndSetCurrent(criteria)L Promise<any> {
  return this.http.get(..).toPromise().then(result => {
    currentSearch.next(result);
    return this;
  });
}

更多关于Subject,您可以check this out

【讨论】:

    猜你喜欢
    • 2021-10-31
    • 2021-10-16
    • 1970-01-01
    • 1970-01-01
    • 2022-11-21
    • 1970-01-01
    • 2023-02-08
    • 2019-04-17
    • 2016-09-12
    相关资源
    最近更新 更多