【发布时间】:2017-05-24 23:32:14
【问题描述】:
我在 a.Net 核心项目中使用 Aurelia v4.6.1 和 Typescript。我有一个组件,它从外部源检索数据并使用 repeat.for 属性将其显示在表中。
现在我想突出显示已选择(单击)的行。在我的视图模型上,我有一个 Document[] 类型的文档属性,它包含网格中显示的所有文档,并且我有一个 Document 类型的 selectedDocument 属性,它应该包含最后一个选定的文档。这是在 setSelected 行的点击事件中设置的。
我的看法如下:
<template>
<require from="../../resources/valueconverters/itemIdFormat"></require>
<require from="./documentData.css"></require>
<h1>Patient Documents</h1>
<p>This component demonstrates fetching data from DME.</p>
<p if.bind="!documents"><em>Loading...</em></p>
<table if.bind="documents" class="table">
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Patient</th>
</tr>
</thead>
<tbody>
<tr repeat.for="document of documents" click.trigger="setSelected(document)" class="${($document.title == $selectedDocument.title) ? 'selected' : 'notSelected'}">
<td>${ document.itemId | itemIdFormat }</td>
<td>${ document.title }</td>
<td>${ document.patient.lastName}, ${ document.patient.firstName }</td>
</tr>
</tbody>
</table>
我的 ViewModel 类是:
import { HttpClient } from 'aurelia-fetch-client';
import { BindingEngine, inject } from 'aurelia-framework';
@inject(HttpClient, BindingEngine)
export class DocumentData {
public documents: Document[];
public selectedDocument: Document;
public bindingEngine
constructor(http: HttpClient, bindingEngine) {
this.bindingEngine = bindingEngine;
this.selectedDocument = null;
let subscription = this.bindingEngine
.propertyObserver(this, 'selectedDocument')
.subscribe(this.selectedDocumentChanged);
http.fetch('/api/Data/PatientDocuments')
.then(result => result.json() as Promise<Document[]>)
.then(data => {
this.documents = data;
});
}
setSelected(selected: Document) {
this.selectedDocument = selected;
}
selectedDocumentChanged(newValue, oldValue) {
// this.documents.forEach(function (d) {
// d.isCurrent = d === newValue;
// })
}
}
正如您在视图 html 中看到的,我在表格行元素上设置了 class 属性:
class="${($document.title == $selectedDocument.title) ? 'selected' : 'notSelected'}"
但是由于某种原因,这总是返回 true,因此所有行都被突出显示。
所以我尝试了这个:
class="${$document.isCurrent ? 'selected' : 'notSelected'}"
然后我在selectedDocument 属性上使用绑定引擎订阅功能,将其设置为运行selectedDocumentChanged 方法,以便在selectedDocument 属性更改时手动设置列表中每个文档的isCurrent 属性。但是请注意,这已被注释掉。这是因为 this 变量不在订阅者更改方法的范围内,所以我无法使用它。
所以我有点卡住了。突出显示所选行的正确方法是什么?我想可能可以使用为每一行重复的嵌套组件,但我希望能够在这个组件中实现这一切。
【问题讨论】:
-
看起来你真的走在了正确的轨道上——我有点困惑为什么
this超出了你的selecteddocumentChanged方法的范围——不应该。但是 -newValue可能不在范围内 - 你可以切换到this.document.forEach((d) => {- 所以你使用的是箭头函数吗?这将保留您的父方法的范围。 -
是的,我也不知道为什么它超出了范围。实际错误是:未捕获的类型错误:无法读取未定义的属性“文档”(“此”未定义)。我尝试使用箭头函数语法,但没有任何区别。因为“this”是未定义的,所以无论如何它都不会到达语句的那一部分。
-
你可以试试
@observable装饰器而不是this.bindingEngine.propertyObserver吗?这将使用相同的selectedDocumentChanged()方法,而无需使用绑定引擎。可能会解决范围问题。 -
是的,这确实解决了问题,谢谢!当您使用 @observable 并且 isCurrent 属性现在设置正确时,“this”在范围内。但是,视图不会自动更新,因为它不会重新计算 class="${$document.isCurrent ? 'selected' : 'notSelected'}"。关于我如何做到这一点的任何想法?
-
我很快就在我的应用程序中测试了它,它对我有用。是否需要
${document...而不是${$document...?
标签: javascript typescript aurelia