Как разрешить функцию sortbydate (), когда я Observable.interval - PullRequest
0 голосов
/ 11 мая 2018

У меня есть этот JSON:

{
    "StatusCode": 0,
    "StatusMessage": "OK",
    "StatusDescription": [
        {
            "id": "1",
            "datetime_device": "2018-05-11 12:05:00",
            "client_name": "Client1"
        },
        {
            "id": "2",
            "datetime_device": "2018-05-11 12:05:00",
            "client_name": "Client1"
        },
        {
            "id": "3",
            "datetime_device": "2018-04-11 12:05:00",
            "client_name": "Client1"
        },
        {
            "id": "4",
            "datetime_device": "2018-01-11 12:05:00",
            "client_name": "Client1"
        },
        {
            "id": "5",
            "datetime_device": "2018-02-11 12:05:00",
            "client_name": "Client2"
        },
        {
            "id": "6",
            "datetime_device": "2018-01-05 12:05:00",
            "client_name": "Client2"
        },
        {
            "id": "7",
            "datetime_device": "2018-05-09 12:05:00",
            "client_name": "Client1"
        },
        {
            "id": "8",
            "datetime_device": "2018-05-01 12:05:00",
            "client_name": "Client1"
        },
        {
            "id": "9",
            "datetime_device": "2018-01-01 12:01:00",
            "client_name": "Client1"
        }
    ]
}

Я создаю функцию, которая сортирует по дате этот JSON.

  private getTime(date?: Date) {
    return date != null ? date.getTime() : 0;
  }
  public sortbydate(): any[] {
    return this.notification0.sort((a, b) => {
      return this.getTime(new Date(a.datetime_device)) - this.getTime(new Date(b.datetime_device));
    }
    );
  }

В html:

  <div class="input-field col s2">
      <mat-checkbox class="example-margin" (click)="sortbydate()">Time</mat-checkbox>
    </div>

до этого момента он работает очень хорошо

Теперь я использовал функцию, которая вызывает в интервале 10000 эту функцию.this.getallnotif();

 public notification: Notifications[];
  ngOnInit() {
    this.subscription = Observable.interval(10000).subscribe(x => {
      this.getallnotif();
    });

  getallnotif() {
    this.ws.notif().subscribe(
      notification => {
        console.log(notification)
        this.notification = notification;
      }
    );
  }

service.ts

  public notif(): Observable<Notifications[]> {
    let headers = new Headers();
    headers.append('x-access-token', this.auth.getCurrentUser().token);
    return this.http.get(Api.getUrl(Api.URLS.notif), {
      headers: headers
    })
      .map((response: Response) => {
        let res = response.json();
        if (res.StatusCode === 1) {
          this.auth.logout();
        } else{
          return res.StatusDescription.map(notiff => {
            return new Notifications(notiff);
          });
        }

      });
  }

Этот код в настоящее время работает, события вызываются в этом интервале, а функция заказа сортирует даты по порядку.Когда я нажимаю кнопку sortbydate (), мои данные сортируются должным образом, но только в течение промежутка времени 10000. Я хочу, чтобы мои данные оставались отсортированными после этого интервала.

У вас есть идеи, как мне это сделать??

Обновление:

Я пробовал этот код

 this.subscription = Observable.interval(10000).subscribe(x => {
    let notification = this.sortbydate();
    if (x >= notification.length) {
      x = notification.length
         }
         console.log(notification0[x]) // data are all of time sorted but new events not show, only when I refresh page. Please any idea why?
         return notification0[x]
     });

1 Ответ

0 голосов
/ 11 мая 2018

Вы захотите использовать переменную для определения порядка сортировки уведомлений.Если у вас больше, чем просто дата, вам нужно будет сделать что-то еще, кроме этого простого примера.

isSortedByDate = false;

Затем, когда вы нажмете кнопку для сортировки, вы захотите установить для этого свойства значение true.

public sortbydate() {
    this.isSortedByDate = true;

    this.notification.sort((a, b) => {
        return this.getTime(new Date(a.datetime_device)) - this.getTime(new Date(b.datetime_device));
    });
}

Затем, когда вы получаете новые уведомления, вы захотите проверить это свойство и отсортировать.

this.ws.notif().subscribe(notification => {
    console.log(notification)
    this.notification = notification;

    if (this.isSortedByDate) {
        this.sortbydate();
    }
});

На другой ноте это считается анти-паттерном.иметь subscribe вложенный в subscribe в rxjs.Вы можете сделать то же самое без этой секунды subscribe.На самом деле было бы лучше, если бы вы не использовали subscribe s, поэтому вам не нужно заботиться об отмене подписки (используя асинхронный канал):

private isSorted = false;
private notificationsSubject$ = new Subject<Notifications[]>();
notifications$ = this.getNotifications();

private getNotifications(): Observable<Notifications[]> {
    return Observable.interval(10000)
        .concatMap(() => this.ws.notif())
        .merge(this.notificationsSubject$)
        .map(notifications => this.isSorted ? this.sort(notifications) : notifications);
}

private sort(notifications: Notifications[]): Notifications[] {
    return [...notifications].sort((a, b) => {
        return this.getTime(new Date(a.datetime_device)) - this.getTime(new Date(b.datetime_device));
    });
}

sortByDate(notifications: Notifications[]) {
    this.isSorted = true;
    this.notificationsSubject$.next(notifications);
}

Затем в вашем шаблоне, где выв настоящее время циклы над уведомлениями, вам нужно будет использовать async канал.Вы можете добавить <ng-template>, чтобы удерживать ссылку на уведомления для метода сортировки, используя *ngIf, например, так:

<ng-template *ngIf="notifications$ | async as notifications">
    <divOrWhateverYouHave *ngFor="let notification of notifications"></divOrWhateverYouHave>
    <div class="input-field col s2">
        <mat-checkbox class="example-margin" (click)="sortByDate(notifications)">Time</mat-checkbox>
    </div>
</ng-template>

Я собрал StackBlitz, чтобы показать всеэто работает вместе .

...