Angular --- Как сбросить таймер обратного отсчета в сообщении Websocket? - PullRequest
0 голосов
/ 01 июня 2019

Я использовал решение таймера обратного отсчета из этого примера: Stackblitz --- Это из принятого ответа на этот вопрос.

Разница в том, что я неИспользовать ввод html для сброса моего таймера, но сообщение Websocket выглядит следующим образом (разница заключается в переключателе):

turn-timer.directive.ts:

@Directive({
  selector: '[counter]'
})
export class CounterDirective implements OnChanges, OnDestroy {

  private counter$ = new Subject<any>();
  private countSub$: SubscriptionLike;

  @Input() counter: number;
  @Input() interval: number;
  @Output() value = new EventEmitter<number>();

  constructor(private client: ClientService)
  {

    this.countSub$ = this.counter$.pipe(
      switchMap((options: any) =>
        timer(0, options.interval).pipe(
          take(options.count),
          tap(() => this.value.emit(--options.count))
        )
      )
    ).subscribe();

    this.client.messages.subscribe(msg =>
    {
      switch (msg.SUBJECT)
      {
        case 'TT_UPDATE':
        {
          this.counter = msg.COUNTER;
        }
        break;
        default:
        break;
      }
    });
  }

  ngOnChanges() {
    this.counter$.next({ count: this.counter, interval: this.interval });
  }
  ngOnDestroy() {
    this.countSub$.unsubscribe();
  }
}

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

turn-timer.component.ts:

@Component({
  selector: 'app-turn-timer',
  templateUrl: './turn-timer.component.html', 
  styleUrls: ['../../../../angry_styles.css']
})

export class TurnTimerComponent implements OnInit
{
    public counter : number = 60;
    interval = 1000;
    public current_player: string;

    constructor (private ll: LL, private client: ClientService, private players: PlayersInfo)
    {
        this.client.messages.subscribe(msg =>
        {
            switch (msg.SUBJECT)
            {
                case 'TT_UPDATE':
                {
                    this.counter = msg.COUNTER;
                    this.current_player = msg.PLAYER_ON_TURN;
                }
                break;
                default:
                break;
            }
        });
    }
    ngOnInit(): void {}
}

Существует HTML:

<ng-container [counter]="counter" [interval]="interval" (value)="value = $event">
    <span>{{ value }}</span>
</ng-container>

Первоначальный автор ответа содержал

<input type="number" [(ngModel)]="counter"/>

в своем html и каждый раз, когда значение этого

<input>

менялось, таймер обратного отсчета сбрасывалсяк этому значению.Однако в моем приложении он должен быть сброшен сервером C #, который отправляет сообщения Websocket.

Итак, какой результат я ожидаю: Для каждого сообщения "TT_UPDATE" я ожидаю {{value}} в HTMLизменить значение msg.COUNTER.Затем this.counter $ .pipe уменьшает {{value}}.Это работает нормально.Просто сбрасывающая часть не работает.

Кстати.Каждое сообщение было успешно получено, я проверил названия полей.Вот определение сообщений:

export interface Message {
  SUBJECT: string;
  COUNTER?: number;       // This is the problematic field.
  PLAYER_ON_TURN?: string;
}

@Injectable()
export class ClientService
{
  public messages: Subject < Message > ;

  constructor(wsService: WebsocketService) {
    this.messages = < Subject < Message >> wsService
      .connect(CHAT_URL).pipe(
        map((response: MessageEvent): Message => {
          console.log(response);
          const data = JSON.parse(response.data);
          return data;
      }), share());
  }

Я удалил импорт и пути из кода, чтобы он был короче, но они были правильными.Также не было ошибок в консоли браузера.

1 Ответ

0 голосов
/ 02 июня 2019

В конце концов, я сам нашел решение.Я даже не нуждался в этом. Счетчик для этого.Я изменил то, что происходит после получения сообщения:

this.client.messages.subscribe(msg =>
{
  switch (msg.SUBJECT)
  {
    case 'TT_UPDATE':
    {
      this.ResetTimer(msg.COUNTER);    // THIS IS NEW !!!
    }
    break;
    default:
    break;
  }
});

}

Затем я создал новый метод, который сбрасывает таймер обратного отсчета до значения, полученного из сообщения:

ResetTimer(updatedValue: number)
  {
    this.counter$.next({ count: updatedValue, interval: this.interval });
  }

Поскольку я не изменяю интервал, я позволяю ему быть таким же.Иногда мне интересно, как все просто.

...