2016-12-13 1 views
0

Я переписываю простой компонент вида Angular2 для использования Observables и асинхронной трубки. Он отображает список результатов, и есть выделенный результат, который должен быть выделен.Выделите выбранный элемент с помощью Angular2 и RxJs

Перед мой компонент имел следующие свойства:

results: Result[] = []; 
selectedResult: Result = null; 

и цикл в представлении выглядел примерно так:

<div *ngFor="let r of results" [class.active]="r === selectedResult" /> 

Теперь у меня есть следующий вид компонента с наблюдаемыми:

@Component({ 
    moduleId: module.id, 
    selector: 'results-view', 
    templateUrl: 'results-view.component.html' 
}) 
export class ResultsViewComponent implements OnInit { 

    constructor(private resultService: ResultService, 
     private route: ActivatedRoute) { } 

    results: Observable<Result[]> = null; 
    selectedResult: Observable<Result> = null; 

    private selectRequests = new Subject<string>(); 

    ngOnInit(): void { 
     let deviceId = this.route.snapshot.params['deviceId'] 

     this.results = this.resultService.getResults(deviceId); 
     this.selectedResult = Observable.combineLatest(this.selectRequests.asObservable(), this.results, (sr, res) => { 
      return res.filter(r => r.resultId == sr)[0]; 
     });  
    } 

    selectResult(resultId: string): void { 
     this.selectRequests.next(resultId); 
    } 
} 

И следующий вид:

<table class="table table-hover"> 
    <thead> 
     <tr> 
      <th>Alert</th> 
      <th>Actions</th> 
     </tr> 
    </thead> 
    <tbody> 
     <tr *ngFor="let r of (results | async)" [class.active]="r === selectedResult"> 
      <td>{{r.Name}}</td> 
      <td> 
       <a href="javascript:void(0)" (click)="selectResult(r.resultId)"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></a> 
      </td> 
     </tr> 
    </tbody> 
</table> 

Это не работает. Я также пробовал угловое выражение

"r === (selectedResult | async)" 

но он также не работает. Единственное, что произошло, это то, что метод getResults выполнялся несколько раз против сервера.

Каков правильный способ обработки выбора с помощью наблюдаемых?

+0

'(selectedResult | async)' должно быть хорошо, обратите внимание, что с '===' вы сравниваете ссылки на объекты, но они должны быть одинаковыми, поэтому попробуйте просто распечатать результат 'async' с помощью' {{selectedResult | async}} 'и посмотреть, что он делает – martin

ответ

0

Вот как это работает сейчас:

В представлении я не сравниваю ссылок на объект больше, но идентификаторы объекта (строки). Таким образом, цикл в представлении выглядит следующим образом:

<tr *ngFor="let r of (results | async)" [class.active]="r?.resultId == (selectedResult | async)?.resultId"> 

Это оставило меня с проблемой, что для каждой строки создается новая подписка создается в свою очередь, вызвало getResult() обратно на сервер.

Моя первая попытка была изменить мой наблюдаемым как это:

this.results = this.resultService.getResults(deviceId).share(); 

Funnily это еще оставил меня с двумя вызовами на сервер (почему ???). Но это, кажется, работает хорошо:

this.results = this.resultService.getResults(deviceId).publishLast().refCount(); 

Это решение было вдохновлено this блоге.

Смежные вопросы