Наблюдаемый строковый массив с использованием асинхронного канала не обновляет представление внутри события nouislider.on - PullRequest
1 голос
/ 30 апреля 2019

Я пытаюсь внедрить noUiSlider в свой компонент поиска.

У меня есть asyncCars: Observable<String[]>;, который содержит отфильтрованные результаты и отображается на ngOnInit() с использованием канала async.

У меня есть событие this.noUiSlider.on('end', this.myLogSliderEnd);, вызываемое при отпускании ручек ползунка. Наблюдаемый массив обновляется, но не обновляет представление.

Может кто-нибудь помочь в этом вопросе? Ниже я показал мой код, где проблема.

component.html

<ng-container *ngFor="let car of asyncCars | carFilter: queryString | async |  paginate: { id: 'server', itemsPerPage: 50, currentPage: p, totalItems: total }">
</ng-container>

component.ts

declare var asyncCars: Observable<String[]>;
declare var carsResult: any;

interface IServerResponse {
    items: string[];
    total: number;
}

@Component({
    moduleId: module.id,
    selector: 'list-carsExample2',
    templateUrl: '/AngularCarSearch/src/app/cars/CarSearchDisableFilterExample.component.html',
    changeDetection: ChangeDetectionStrategy.OnPush
})

export class CarSearchDisableFilterExample {

    cars = [];
    filterArr = [];
    asyncCars: Observable<String[]>;
    p: number = 1;
    total: number;
    loading: boolean;

    noUiSlider: any;
    @ViewChild('priceSlider') priceSlider;

    public ngOnInit(): void {

        this.cars = carsResult;

        this.getPage(1);

        this.noUiSlider = this.buildSlider([this.minimumPrice, this.maximumPrice], this.priceSlider, priceDropdownValues, [this.sliderMin, this.sliderMax], '£{0}', false);

        this.updateSlideLimits()
    }

    updateSlideLimits() {
        this.noUiSlider.on('end', this.myLogSliderEnd);
    }

    public myLogSliderEnd = (values: any[], handle) => {

        //Add the two values set on the slider to filterArray        
        this.filterArr = AddPriceToFilter([values[0], values[1]], false, this.filterArr);

        //Do the search based on what is in filter array
        this.cars = multiFilterSearch(carsResult, this.filterArr);


        this.getPage(1);
    }

    getPage(page: number) {
        this.loading = true;
        this.asyncCars = serverCall(this.cars, page)
            .do(res => {
                this.total = res.total;
                this.p = page;
                this.loading = false;
            })
            .map(res => res.items);
    }
}

/**
* Simulate an async HTTP call with a delayed observable.
*/
function serverCall(cars, page: number): Observable<IServerResponse> {
    const perPage = 50;
    const start = (page - 1) * perPage;
    const end = start + perPage;

    var ob = Observable
        .of({
            items: cars.slice(start, end),
            total: cars.length
        }).delay(100);
    return ob
}

/**
* Filters an array of objects with multiple criteria.
*
* @param  {Array}  array: the array to filter
* @param  {Object} filters: an object with the filter criteria as the property names
* @return {Array}
*/
function multiFilterSearch(array, filters) {
    const filterKeys = Object.keys(filters);
    // filters all elements passing the criteria
    return array.filter((item) => {
        // dynamically validate all filter criteria
        return filterKeys.every(key => {
            // ignores an empty filter
            if (!filters[key].length) {
                return true;
            }
            else if (key === "Price") {
                return (item.PriceRetail >= filters["Price"][0] && item.PriceRetail <= filters["Price"][1])
            }
            else {
                return filters[key].includes(item[key]);
            }
        });
    });
}

function AddPriceToFilter(event, checked, filterArr) {

    if (checked === false) {

        if (event[0] === 'Any' && event[1] === 'Any') {

        }
        else {

            filterArr["Price"] = [event[0], event[1]];
        }
    }

    return filterArr;
}

Я ожидал, что представление будет обновлено, потому что наблюдаемые значения asyncCars изменились, но это не отражается на представлении?

1 Ответ

0 голосов
/ 30 апреля 2019

Вы назначаете новую Наблюдаемую asyncCars в getPage.Это проблема.Что вы, вероятно, хотите сделать, это добавить значение в уже существующий поток.Используйте Subject для достижения этой цели.

asyncCars = new Subject<String[]>();

getPage(page: number) {
    this.loading = true;
    serverCall(this.cars, page)
        .do(res => {
            this.total = res.total;
            this.p = page;
            this.loading = false;
        })
        .map(res => res.items)
        .subscribe(
            cars => this.asyncCars.next(cars)
        );
}
...