json - 如何将 Angular 中 JSON 文件或 REST 响应中的值与服务映射到两个(或更多)打字稿对象的属性中?
问题描述
虽然我觉得这个答案比较接近我的问题并且得到了一些声誉,但我没有得到正确的答案。我阅读了很多关于如何在 Angular 中使用“新”样式的观察者模式((...).pipe(map(...)).subscribe(...)
和*ngFor="... | async"
)的文章,现在还偶然发现了如何在 Angular 中避免 Observables。我不想避免反应性行为;我希望 REST-API 中的更改能够“实时”反映给用户,而无需重新加载观察者。这就是为什么我想将一个对象(以及它的属性)订阅到一个 Observable(以及其中的数据流中的“可能存在”值),对吧?
在我的模板中,我有:
<p>Werte:<br><span *ngFor="let attribute of _attributes | slice:0:5; index as h">
{{attribute.name}}: <strong>{{getParamNameAt(h)}}</strong> </span><br>
<span *ngFor="let attribute of _attributes | slice:5: _attributes.length; index as h">
{{attribute.name}}: <strong>{{getParamNameAt(h + 5)}}</strong> </span></p>
在我的组件中,我有:
private _attributes: Attribute[];
constructor(private attributesService: BkGenericaAttributesService) {
attributesService.getAttributes().subscribe({ next: attributes => this._attributes = attributes });
}
getParamNameAt(h: number): string {
let attrVal = this.bkHerstArtNr.charAt(h);
return attributes[h].subModule.find(param => param.subModuleValue === attrVal).subModuleName;
}
作为服务,我有:
const localUrl = '../../assets/json/response.json';
@Injectable()
export class BkGenericaAttributesMockService implements BkGenericaAttributesService {
constructor(private http: HttpClient) {
}
getAttributes(): Observable<Attribute[]> {
return this.http.get<Attribute[]>(localUrl).pipe(
tap((attributes : Attribute[]) => attributes.map((attribute : Attribute) => console.log("Piping into the http-request and mapping one object after another: " + attribute.name))),
map((attributes : Attribute[]) => attributes.map((attribute : Attribute) => new Attribute(attribute.id, attribute.name, attribute.title, attribute.description,
(attribute.parameters ? attribute.parameters.map((parameter : Parameter) => new Parameter(parameter.id,
parameter.name, parameter.value)) : [])))));
}
此时我运行应用程序的问题是“to-create-on-stream” Attribute
-objects 和“nested”Parameters[]-array(通过将Parameter
-objects 推入其中创建)_attributes
从 httpClient 的 Observable:推入 -array Piping into the http-request and mapping one object after another: undefined
。
除此之外- 我的构造是从 JSON 文件(或者 API 流,当用户访问 SPA 时可能会发生变化)读取值到 Angular 视图上显示的多个对象的属性的正确方法?
有了上面提到的答案- 或者我认为我必须将它翻译成我的代码的方式 - 我开始怀疑我是否真的理解(并使用)了 Data-Providers <= Observables => Operators => 的反应式 Angular 方式向用户显示订阅者,最后是观察者。
我真的很困惑(如您所见),因为到目前为止我发现的许多答案和描述都使用较旧的模式(在 Angular 5.5 之前?)和/或部分相互矛盾。
我是否在正确的位置处理 API 更改?模板的*ngFor
-directives 的数组是否是一个观察者(用 处理| async
)或者数组中的变化将由模板后面的模型处理,并且模板获取它的新值(使用插值和属性绑定)以及指令在没有async
ing的情况下更改组件属性?
简而言之: 是否有一个 for-dummies 默认指令将来自 http 请求的值“流式读取”到多个 Typescript 对象中,并且它们的属性同时显示在模板中,并且仅在相关的 DOM 节点中呈现实时更改指令, Angular 8 自以为是的方式?“Stream-reading”的意思是:(仅)在 API 发生变化时拉取和推送,不浪费资源。
解决方案
如果我理解正确,您希望服务器在更改发生后立即将更改推送到客户端,以便客户端可以做出相应的反应并呈现,对吗?
this.http.get
是一个单独的调用,它将通过数据的快照来解决。这意味着它不会因为后端中的某些数据发生更改而自动更新。
如果您想通知客户端有关新数据的信息,或者甚至将该数据直接发送到客户端,您将需要 websockets。
代码也存在一些问题:
- 如果你
.subscribe()
,你将需要.unsubscribe()
,否则你最终会出现内存泄漏。 param => param.value === attrVal
,从哪里来attrVal
,我没有看到它在方法中被设置在任何地方?- 您应该使用
async
管道,因为它会自动为您取消订阅。 - 您不需要通过
new
在您的服务中创建类实例,而是您的Attribute
输入应该是一个接口。
推荐阅读
- php - 从我的网络服务器上的文件夹下载 zip 文件
- c# - Roslyn 中的 INamedTypeSymbol 继承关系
- c# - 如何使用 Refit 反序列化数组?
- blockchain - Composer Playground 无法加载示例业务网络
- function - TypeScript:函数表达式重载
- database - 使用多个可选参数在 H2 数据库中实现搜索查询
- android - Stripe PaymentMethodsActivity 添加谷歌支付按钮
- php - For 循环仅显示最终结果
- java - 模拟 BouncyCastle 类 - SecurityException
- python - Tensoflow Estimator:如何使用 tf.graph_util.convert_variables_to_constants