首页 文章

如何将数据从父级传递给子级多次

提问于
浏览
1

我正在构建一个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片段

<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>

父对象的submitSearch()方法在父表单提交时调用 . 它导航到子组件并显示searchResult . 直到现在它工作正常 .

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

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

2 回答

  • 1

    目前尚不清楚你是如何做到这一点的 . 你说 SearchResultComponentSearchFormComponent 的孩子,但你导航到它就像在运行 setSearchCriteria 之后它自己的组件一样 . 既然我们很难理解发生了什么 .

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

  • 1

    你应该在 SearchService 里面 Subject . 称之为 currentResult . 一个主题就像一个双向可观察者,它既是 生产环境 者又是消费者 . 因此,在父端,您可以成为 生产环境 者,子项结束消费者 .

    您可能不希望在onInit中设置搜索条件,但在父级中发生某些操作时 . 然后你可以为孩子产生一些 Value ,这将是聆听 .

    也许这样的事情

    从'rxjs / 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 ,孩子可以订阅 . 无论何时父母调用搜索,当结果进入时,孩子都会得到它 .

    如果要对父项中的结果执行某些操作,可以使搜索方法返回一个promise

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

    有关 Subject 的更多信息,您可以check this out

相关问题