可以通过单击按钮取消Angular 2打字稿中的Observable并触发新的

时间:2017-11-15 18:11:28

标签: angular typescript observable

我的UI中有三个按钮。每个Button都会触发一个Observable到另一个后端服务器端点。

例如:

  1. 按钮1:HTTP GET可观察到https://endpoint1.something?params=whatever
  2. 按钮2:HTTP GET可观察到https://endpoint2.something?params=whatever
  3. ...

    描述

    basicUI

    每个蓝色按钮都需要触发三个不同的端点,并在单击相应按钮后为用户提供输入框下方的一些自动完成功能(实例,单击hasProperty按钮时显示<hasProperty>并且任何建议如下所示)。 autocompletion

    问题

    在我选择hasSeatBelt之后,然后点击hasValue按钮,我仍然可以从之前的hasProperty观察中获得建议 Problem

    点击其他按钮时,有没有办法取消上一个Observable

    Code Snippets

    component.html (可观察数据的输入框+ <code></code> +空格)

    <div class="row">
            <div class="col-12">
                <h5>Your Semantic Query</h5>
                <code>
                    {{sentence | json}}
                </code>
                <div class="form-group">
                    <form class="form-inline">
                        <input type="search" class="form-control"
                               [(ngModel)] = "sentence"
                               [formControl]="searchField"
                               (keydown)="selected = false; true;"
                        #searchbox style="width: 500px;">
                    </form>
                </div>
                <div>
                    <p class="lead" *ngIf="loading">Loading...</p>
                </div>
                <ul class="list-group ac-keywords" *ngIf="searchField.value !== '' && !selected">
                    <li class="list-group-item"
                        *ngFor="let eachProp of results | async" (click)="searchbox.value = eachProp.translated; selected=true; sentence=sentence+eachProp.translated;"
                    >
                        {{eachProp.translated}}
                    </li>
                </ul>
            </div>
        </div>
    

    component.html(按钮)区域

    <div class="btn-group">
                        <li>
                            <button class="btn btn-primary btn-lg"
                                    (click)="hasPropertyRelation('hasProperty')"> hasProperty </button>
                        </li>
                        <li>
                            <button class="btn btn-primary btn-lg"
                                    (click)="hasValueRelation('hasValue')"> hasValue </button>
                        </li>
                        <li>
                            <button class="btn btn-primary btn-lg" #refBtn
                                    (click)="hasReferenceRelation('hasReference')"> hasReference </button>
                        </li>
                        <li *ngFor="let eachButton of objectRelationsButton['listOfSQP']">
                            <button class="btn btn-warning btn-lg" #objBtn (click)="objectPropRelation(eachButton)">
                                {{eachButton}}
                            </button>
                        </li>
                    </div>]
    

    component.ts

        private loading: boolean = false;
        public objectRelationsButton: Object = {};
        public sentence: any;
        private results: Observable<SearchItem[]>;
        private searchField: FormControl;
        selected: boolean = false;
        @Input() configSPQ: Object;
        @Input() lang: string;
        constructor(private backendCall: backednCallService) {}
    
        ngOnInit(): void {
            this.searchField = new FormControl();
            // get the yellow buttons from server..
            let dummyJSON = this.configSPQ;
            this.backendCall.getSQPButton(dummyJSON)
                .then(res => this.objectRelationsButton = res);
            this.sentence = this.configSPQ['frozenConcept'];
        }
    
        // Blue hasProperty Button
        hasPropertyRelation(inputVal: string) {
           // add text dynamically
           this.sentence += ' <' + inputVal + '> ';
            // HTTP Observable
            this.results = this.searchField.valueChanges
                .debounceTime(400)
                .distinctUntilChanged()
                .do( _ => this.loading = true)
                .switchMap(term =>
                    this.expSearch.searchForProperty(this.configSPQ)
                )
                .do( _ => this.loading = false);
        }
    
        // hasValue Blue Button
        hasValueRelation(inputVal: string) {
            // CANCEL PREVIOUS OBSERVABLE MAYBE HERE
            this.sentence += ' <' + inputVal + '> ';
        }
    
        hasReferenceRelation(inputVal: string) {
            this.sentence += ' <' + inputVal + '> ';
        }
    
        objectPropRelation(inputVal: string) {
            this.sentence += ' <' + inputVal + '> ';
        }
    

1 个答案:

答案 0 :(得分:0)

如果发出.switchMap,如果发出新值,它将取消之前的http observable。有几种不同的方法可以做到这一点,我会通过将valueChanges observable与一个可以发出值的observable合并然后切换到map并订阅它来实现。

results$ = this.searchField.valueChanges.debounceTime(400).distinctUntilChanged();
cancel$ = new BehaviorSubject(false);

...
this.results = this.results$.merge(this.cancel$).do(() => this.loading = true)
  .switchMap(term => {
    if (term) {
      return this.expSearch.searchForProperty(this.configSPQ);
    }
    return of();
  })
  .do(() => this.loading = false);

然后在其他按钮中,您可以this.cancel$.next(false)取消当前的http搜索。