Аурелия активируется сигналом R

Как я могу использовать signalR с циклом страницы aurelia canActivate() и активировать()? Я имею в виду... В моем конструкторе виртуальной машины я инициализирую соединение signalR. в методах canActivate() или активировать() я запускаю соединение signalR. На стороне сервера, в хабе, когда клиент подключается, я получаю данные для клиента и публикую их подключенному клиенту. Таким образом, клиент Aurelia будет получать данные асинхронно. Так страница будет отображаться пустой, а когда данные придут обновит ее. Но я хочу дождаться данных из концентратора signalR перед отображением страницы.

Итак, рабочий процесс таков:

  1. Конструктор виртуальной машины => Создайте соединение signalR с помощью ( HubConnectionBuilder )
  2. VM Constructor => Установите события подключения, такие как «onConnected»
  3. Активировать VM() => Запустить соединение, вызвав this.connection.start();
  4. SignalR Hub.OnConnectedAsync() => получить данные из БД
  5. SignalR Hub.OnConnectedAsync() => Отправлять данные только новому подключенному клиенту ( Clients.Client(Context.ConnectionId).SendAsync("onConnected", data);)
  6. Обработчик события VM onConnected => получает данные и устанавливает модель (this.model=data)

К моменту, когда рабочий процесс достигает шага номер 4, страница уже отображается пустой.

ВМ

@autoinject
export class AlarmsVM {
  model: any;    
  connection: HubConnection;

  constructor() {
     this.connection = new HubConnectionBuilder()
        .withUrl("/alarmsHub")
        .configureLogging(LogLevel.Information)
        .build();

    this.connection.on("onConnected", (data) => this.model = data);
    this.connection.on("onUpdate", (data) => this.model = data);
  }

  async activate() {
    await this.connection.start().catch(err => console.error(err.toString()));
  }

  async deactivate() {
    await this.connection.stop();
  }
}

концентратор signalR

public class AlarmsHub:Hub
{
    private readonly IMediator _mediator;

    public AlarmsHub(IMediator mediator)
    {
        _mediator = mediator;
    }

    public override async Task OnConnectedAsync()
    {
        var data = await _mediator.Send(new GetAlarmsQuery());
        await Clients.Client(Context.ConnectionId).SendAsync("onConnected", data);
    }

    ...
}

🤔 А знаете ли вы, что...
C# имеет механизм исключений для обработки ошибок и исключительных ситуаций.


232
1

Ответ:

Решено

Согласно документации, вы можете вернуть промис из активации (), и навигация будет происходить только тогда, когда промис разрешается: https://aurelia.io/docs/api/router/interface/RoutableComponentActivate/method/activate/

РЕДАКТИРОВАТЬ

Я неправильно понял ваш первоначальный вопрос, вы в основном хотите, чтобы активация разрешалась при получении события onConnected. Оберните разрешение onConnected в обещание в активации (), и все должно быть хорошо, пример кода:

  activate() {
    this.connection.start().catch(err => console.error(err.toString()));
    return new Promise((resolve, reject) => {
       this.connection.on("onConnected", (data) => {
          this.model = data;
          return resolve();
       });
    });
  }