Разработать программу, чтобы Angular не рендерил компонент MediaStream каждый раз, когда обновление отправляется в хранилище? - PullRequest
0 голосов
/ 22 января 2019

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

В основном у меня два хранилища, я использую библиотеку управления состоянием Акита для этих магазинов.Оба Entity Stores , первое хранилище для всех сообщений и имеет такую ​​подпись:

interface MessageInterface {
 // Unique identifier
 id: ID;
 // The time is was created
 time: number;
 // The actual string message
 value: string;
} 

Второе хранилище для всех моих соединений, соединение имеет подписьнапример:

interface ConnectionInterface {
  // Unique identifier
  id: ID;
  // The MediaStream (webcam stream object)
  stream: MediaStream;
  // An array of unique ids where each id relates to an id in the MessageStore
  messages: ID[] | MessageInterface[]
}

Вот шаги, которые предпринимает приложение, когда оно начинается:

  1. Запускает поток веб-камеры, используя getUserMedia.
  2. Затем сохраняетсгенерированный поток в хранилище соединений.
  3. Затем он начинает создавать 1 сообщение каждую секунду, после создания каждого сообщения сохраняет его в хранилище сообщений и затем связывает это сообщение с хранилищем соединений, добавляя индекссозданное сообщение в начале массива сообщений в сущности ConnectionStore.

Вот пример того, как два хранилища будут выглядеть в конце:

Хранилище сообщений:

entities: {
  3ea9454682: {id: "3ea9454682", time: 1548117443764, value: "CIAO"}
  4a66b34aad: {id: "4a66b34aad", time: 1548117444765, value: "SALAAM"}
  4e165d4887: {id: "4e165d4887", time: 1548117445767, value: "SALAAM"}
  4eb22b42a6: {id: "4eb22b42a6", time: 1548117441763, value: "BONJOUR"}
  5cbc594983: {id: "5cbc594983", time: 1548117447771, value: "HELLO"}
  6c574e44a8: {id: "6c574e44a8", time: 1548117446770, value: "NAMASTE"}
  bfdcc344aa: {id: "bfdcc344aa", time: 1548117448771, value: "NAMASTE"}
  c7c55d45a7: {id: "c7c55d45a7", time: 1548117440762, value: "NAMASTE"}
  cc86a045af: {id: "cc86a045af", time: 1548117442764, value: "HOLA"}
  fd2cf744ab: {id: "fd2cf744ab", time: 1548117439760, value: "CIAO"}
}

Хранилище подключений:

entities: {
  fda7464bbe: {
     id: "fda7464bbe",
     mediaStream: {
       active: true
       id: "bQO4NI86L7pEHNzEwEK9dVht5wtHf5s81TfV"
       onactive: null
       onaddtrack: null
       oninactive: null
       onremovetrack: null
     },
     messages: [
       "bfdcc344aa"
       "5cbc594983"
       "6c574e44a8"
       "4e165d4887"
       "4a66b34aad"
       "3ea9454682"
       "cc86a045af"
       "4eb22b42a6"
       "c7c55d45a7"
       "fd2cf744ab"
     ]
  }
}

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

1 Ответ

0 голосов
/ 22 января 2019

Вы можете решить проблему, используя trackBy в вашем ngFor:

<li *ngFor="let connection of connections | async; trackBy: trackByFunction">

Объявите функцию trackByFunction следующим образом:

trackByFunction(index, item) {
  return index;
}

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

Мне пришлось добавить следующее в ваш polyfills.ts файл, чтобы он компилировался:

import 'core-js/es7/reflect';

Надеюсь, это поможет.

...