Angular 2 (ng2) 在 [class.whatever] 中使用异步管道
Posted
技术标签:
【中文标题】Angular 2 (ng2) 在 [class.whatever] 中使用异步管道【英文标题】:Angular 2 (ng2) using the async pipe in [class.whatever] 【发布时间】:2017-05-05 02:05:18 【问题描述】:我正在开发一个 Angular 2 应用程序,在我的一个组件中我有这个:
<p class="newNode">
<input [(ngModel)]="formNode.id" placeholder="id">
<input [(ngModel)]="formNode.name" placeholder="name">
<input [(ngModel)]="formNode.type" placeholder="image">
<button (click)="addNode()">Add</button>
</p>
<app-node-info *ngFor="let node of ((nodesService.observable | async) | immutableMapOfMaps)"
[node]="node"
[removeNode]="removeNode.bind(this)"
[class.active] = "(viewService.observable | async).get('currentNode') === node.id"
(click) = "viewService.setCurrentNode(node.id)">
</app-node-info>
在浏览器中运行良好,但是当我尝试对匹配的 ts 文件进行 lint 处理时,出现以下 linting 错误:“您尝试访问的方法“异步”在类声明中不存在。(无访问权限) -失踪成员)' 在:'11,21"
我的组件代码如下:
import ChangeDetectionStrategy, Component, OnInit from '@angular/core';
import clone from 'ramda';
import UUID from 'angular2-uuid';
import StateService from '../state.service';
import D3Node from '../../non-angular/interfaces';
import NodesService, ViewService from '../../non-angular/services-helpers';
@Component(
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'app-list-of-nodes',
styleUrls: ['./list-of-nodes.component.css'],
templateUrl: './list-of-nodes.component.html',
)
export class ListOfNodesComponent implements OnInit
formNode: D3Node;
/**
* The injected service from ./state.service
*/
private nodesService: NodesService;
private viewService: ViewService;
constructor(state: StateService)
this.nodesService = state.twiglet.nodes;
this.viewService = state.view;
ngOnInit ()
this.formNode =
id: UUID.UUID(),
name: (Math.random().toString(36) + '00000000000000000').slice(2, 6),
type: (Math.random().toString(36) + '00000000000000000').slice(2, 3),
;
addNode ()
this.nodesService.addNode(clone(this.formNode));
this.formNode =
id: UUID.UUID(),
name: (Math.random().toString(36) + '00000000000000000').slice(2, 6),
type: (Math.random().toString(36) + '00000000000000000').slice(2, 3),
;
removeNode (node: D3Node)
this.nodesService.removeNode(node);
在 ngFor 以外的地方使用异步管道是不是某种反模式?
我知道我可以订阅 observable 并将 response = 设置为某个局部变量,然后比较它而不是使用 [class.active] 中的异步管道,但我宁愿不在我的 .ts 中做某事我可以在我的 html 文件中执行的文件。
有没有办法绕过这个错误,这样我的 linter 就不会对我大喊大叫了?我有检查 linting 的 github 预提交钩子,所以我需要一个永久的解决方案。我确实发现我可以将// tslint:disable-line
放在讨论更改检测的行(第 11 行)并修复它,但我不知道为什么。
【问题讨论】:
错误显示的是哪个文件? - 我不确定你是否应该在你的模板文件上运行 ts-linter,毕竟 angular-expression 不完全是打字稿 name.component.ts 上显示错误,我没有对模板文件进行 linting。但是,如果我从模板文件中删除行[class.active] = "(viewService.observable | async).get('currentNode') === node.id"
,则 linting 会通过。这对我来说很奇怪,就像 tslint 以某种方式导入模板。
这确实很奇怪 - linting 是什么时候完成的?您是否使用 webpack 并且 linting 是在预加载器中完成的?或者在包装过程中的某个时候等?这也很有趣,它没有突出您对async
的其他用途
我在 VS 代码中的 linter 以及当我在终端中运行 `tslint \"src/**/*.ts\ ` 时都会抛出相同的错误。
【参考方案1】:
我认为有一个未解决的问题需要在 codelyzer 中修复。 https://github.com/angular/angular-cli/issues/4351
但在此之前,作为一种解决方法,您可以在您的组件中执行此操作以解决 lint 问题:
// TODO: fix this later
async: any;
constructor(..) ..
【讨论】:
【参考方案2】:我遇到了同样的问题,并且能够像这样使用 安全导航操作符 摆脱 linter 抱怨。对你来说,它可能看起来像这样。
(viewService.observable | async)?.get('currentNode') === node.id
编辑:在codelyzer version 2.0.0-beta.1 中发现了一个错误报告,其中no-access-missing-member
配置设置为true。这对我来说似乎是一个案例。似乎在以后的版本中修复了,虽然我还没有尝试。
【讨论】:
【参考方案3】:不确定这是否能解决问题,但模板表达式很快就会变得混乱,您可以这样做:
<app-node-info ...
[class.active]="(currentNode | async) == node.id">
</app-node-info>
控制器:
export class ListOfNodesComponent implements OnInit
formNode: D3Node;
/**
* The injected service from ./state.service
*/
private nodesService: NodesService;
private viewService: ViewService;
private currentNode: Observable<any>;
constructor(state: StateService)
this.nodesService = state.twiglet.nodes;
this.viewService = state.view;
currentNode = this.viewService.observable
.map(val => val.get('currentNode'));
【讨论】:
欣赏它。我曾想过将其拉入控制器,但后来我失去了使用可观察对象和不可变对象的 OnPush 优势。我可能会将服务本身从组件中拉出,然后使用 @Input() 从订阅中下推一个变量,我只是不知道为什么它在 linting 时遇到问题。 所以将异步逻辑的部分移动到控制器并没有改变任何东西?我以前没有见过,如果您找到解决方案,请在此处发布。 - 也许作为最后一击:您在模板中使用“===”,“==”有什么不同吗? 不,当我将异步移动到控制器中作为订阅时,它工作正常。我只是好奇为什么我不能按照自己的方式去做。 在我的回答中,我没有将订阅移动到控制器中 - 我只是将流的某些部分移到那里,异步仍在模板中 - 不知道为什么它适用于 tslint 但它更干净以上是关于Angular 2 (ng2) 在 [class.whatever] 中使用异步管道的主要内容,如果未能解决你的问题,请参考以下文章
“ng2-CKEditor”节点模块不适用于打字稿[Angular2]
Angular2 切换/打开 ng2-select 下拉菜单
Angular 2 Universal ng2-bootstrap 不工作 Safari