设计程序以便 Angular 不会在每次将更新推送到商店时重新呈现 MediaStream 组件?
Architecting program so that Angular does not re-render the MediaStream component every time an update is pushed to the store?
我创建的示例 Angular 应用程序演示了我遇到的问题,可以找到此应用程序 here
基本上我有两个存储,我正在使用状态管理库Akita for these stores. Both are 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[]
}
以下是应用启动时执行的步骤:
- 使用
getUserMedia
启动网络摄像头流。
- 然后将生成的流保存到 ConnectionStore。
- 然后它开始每秒创建 1 条消息,在创建每条消息后,它将消息保存到 MessageStore 中,然后通过将创建的消息的索引添加到消息的开头将该消息关联到 ConnectionStore 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"
]
}
}
我遇到的问题是每次生成消息并将其保存到商店时,您都会看到网络摄像头视频闪烁。也许我在构建错误的结构?也许有一种方法可以只重新呈现消息而不影响流?任何建议都会有很大帮助,感谢任何尝试解决此问题的人!
您可以通过在 ngFor
:
中使用 trackBy 来解决问题
<li *ngFor="let connection of connections | async; trackBy: trackByFunction">
在您的打字稿中像这样声明 trackByFunction:
trackByFunction(index, item) {
return index;
}
这有助于 Angular 跟踪在列表中添加或删除了哪些项目,并仅重新呈现已更改的项目。
我必须将以下内容添加到您的 polyfills.ts
文件中才能编译:
import 'core-js/es7/reflect';
希望对您有所帮助。
我创建的示例 Angular 应用程序演示了我遇到的问题,可以找到此应用程序 here
基本上我有两个存储,我正在使用状态管理库Akita for these stores. Both are 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[]
}
以下是应用启动时执行的步骤:
- 使用
getUserMedia
启动网络摄像头流。 - 然后将生成的流保存到 ConnectionStore。
- 然后它开始每秒创建 1 条消息,在创建每条消息后,它将消息保存到 MessageStore 中,然后通过将创建的消息的索引添加到消息的开头将该消息关联到 ConnectionStore 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"
]
}
}
我遇到的问题是每次生成消息并将其保存到商店时,您都会看到网络摄像头视频闪烁。也许我在构建错误的结构?也许有一种方法可以只重新呈现消息而不影响流?任何建议都会有很大帮助,感谢任何尝试解决此问题的人!
您可以通过在 ngFor
:
<li *ngFor="let connection of connections | async; trackBy: trackByFunction">
在您的打字稿中像这样声明 trackByFunction:
trackByFunction(index, item) {
return index;
}
这有助于 Angular 跟踪在列表中添加或删除了哪些项目,并仅重新呈现已更改的项目。
我必须将以下内容添加到您的 polyfills.ts
文件中才能编译:
import 'core-js/es7/reflect';
希望对您有所帮助。