我在理解和使用RxJS Observables和ngrx Store时遇到了问题。
我尝试了combineLatest
,过滤器,连接数组等,但似乎无法获得有效的无错解决方案。
对于哪种技术最适合实现此结果的任何意见/反馈我将不胜感激
所有ngOnInit
代码都运行良好我可以访问所需的所有列表,每次选择getSelectedCustomersPeople
运行的另一个客户时。
目前的意大利面条代码,如果你能理解我想做什么
ngOnInit() {
this.peopleStore.dispatch(new fromPeopleStore.LoadPeople());
this.people$ = this.peopleStore.select(fromPeopleStore.getAllPeople);
this.selectedCustomers$ = this.toolbarStore
.select(fromToolbarStore.getSelectedCustomers);
this.selectedCustomers$.subscribe(selected => {
this.selectedCustomersPeople$ = this.getSelectedCustomersPeople();
});
}
getSelectedCustomersPeople(): Observable<Person[]> {
return combineLatest(this.selectedCustomers$, this.people$, (customers, people) => {
const allSelectedPeople = customers.map(
customer => Object.assign(people.filter(
person => person.company === customer.id
))
);
const flattenSelectedPeople = [].concat.apply([], allSelectedPeople);
return flattenSelectedPeople;
});
}
applyFilter(filterValue = ' ') {
filterValue = filterValue.trim();
filterValue = filterValue.toLowerCase();
this.selectedCustomersPeople$ = filterValue;
// Would like to filter here not sure how
}
<mat-table #table [dataSource]="selectedCustomersPeople$ | async"
matSort
[@animateStagger]="{ value: '50' }">
<!-- Name Column -->
<ng-container cdkColumnDef="firstName">
<mat-header-cell *cdkHeaderCellDef mat-sort-header>First Name</mat-header-cell>
<mat-cell *cdkCellDef="let person">
<p class="text-truncate font-weight-600">
{{ person.firstName }} {{ person.familyName }}
</p>
</mat-cell>
</ng-container>
<mat-header-row *cdkHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *cdkRowDef="let person; columns: displayedColumns;"
class="person"
(click)="editPerson(person)"
[ngClass]="{'mat-light-blue-50-bg': checkboxes[person.id]}"
matRipple
[@animate]="{ value: '*', params: { y: '100%' } }">
</mat-row>
</mat-table>
答案 0 :(得分:0)
如果其他人试图做类似的事情,我得到了一个有效的解决方案。下面更新的代码可能不是最好或最干净的方法,但它运作良好:
() -> Void = { [weak self] in
guard let `self` = self else {
self.callMethod2()
}
self.callMethod3()
}
答案 1 :(得分:0)
我做了一个基本的例子,说明如何通过使用rx流来做得更清洁。
我做了一个基本的独立示例,其中我创建了两个源(客户$和公司$),它们将发出所有0.8 - 1秒。这只是我可以在本地测试。你应该能够使用people $和selectedCompanies $ observables来做同样的事情。
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/interval';
import 'rxjs/add/observable/combineLatest';
interface Customer {
id: number;
company: number;
}
interface Company {
id: number;
}
export function test() {
// Emits a customer list all 1000 milliseconds
const customers$: Observable<Customer[]> = Observable
.interval(1000)
.map(() => <Customer[]>[{ id: 1, company: 1}, {id: 2, company: 1}, {id: 3, company: 5}]);
// Emits a company list all 800 milliseconds
const companies$: Observable<Customer[]> = Observable
.interval(800)
.map(() => <Customer[]>[{ id: 1, company: 1}, {id: 2, company: 1}]);
// Create a stream that combines the latest value of both lists
const both$ = Observable.combineLatest(customers$, companies$);
// Create a new observable which will emit the filtered customers
const filteredCustomers$ = both$.map((data: any) => {
const customers: Customer[] = data[0];
const companies: Company[] = data[1];
// We did not receive any companies, so we can return the full customer list
if (!companies || companies.length === 0) {
return customers;
}
// Create an object that will have keys of existing companies as id
const companyIds = {};
companies.forEach(c => companyIds[c.id] = true);
// Return the filtered version of the customers
return customers
// In the filter statement, we check if the company id exists
// in our helper object. You could leave out the "=== true" part.
.filter(customer => companyIds[customer.company] === true);
});
// Now we have a filteredCustomers$ observable where we can subscribe:
filteredCustomers$.subscribe(customers => console.log('Filtered Customers: ', customers));
}