我在a.Net核心项目中使用Aurelia v4.6.1和Typescript。我有一个组件,它从外部源检索数据,并使用repeat.for属性将其显示在表中。
现在我想突出显示已选中的行(单击)。在我的视图模型上,我有一个Document []类型的文档属性,它包含网格中显示的所有文档,并且我有一个类型为Document的selectedDocument属性,它应该包含最后选择的文档。这是在setSelected行上的click事件中设置的。
我的观点如下:
<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
变量不在订阅者更改方法的范围内,因此我无法使用它。
所以我有点卡住了。突出显示所选行的正确方法是什么?我想可能有可能使用为每一行重复的嵌套组件,但我宁愿能够在这个组件中实现这一切。
答案 0 :(得分:1)
首先 - 您使用selectedDocumentChanged()
方法获得的范围问题是因为您正在使用绑定引擎。如果您使用可观察装饰器而不是如下所示,this
将不再超出范围;
import {observable} from "aurelia-framework";
export class DocumentData {
@observable selectedDocument;
// Your other code
selectedDocumentChanged(newVal, oldVal) {
this.documents.forEach(function (d) { // no longer out of scope
d.isCurrent = d === newValue;
})
}
}
其次 - 在您的模板中,您不需要使用$
为您的媒体添加前缀。仅在您希望在模板中使用字符串插值时使用此选项。如果您正在循环或比较属性,那么您可以正常使用它们。例如;
class="${document.isCurrent ? 'selected' : 'notSelected'}"
或
class="${(document.title == selectedDocument.title) ? 'selected' : 'notSelected'}"