将@computedFrom与Aurelia中的FileList一起使用

时间:2016-02-11 08:44:32

标签: javascript aurelia aurelia-binding

我在视图中更新时没有更新的值存在问题。

<div class="form-group">
    <label>Files</label>
    <input type="file" multiple files.bind="fileList" class="form-control" />
</div>

<tr repeat.for="projectDocument of projectDocumentItems">
    <td>
        <input type="text" value.bind="projectDocument.file.name" class="form-control" />
    </td>
    <td>${projectDocument.file.size}</td>
    <td>${projectDocument.file.type}</td>
    <td>
        <input type="text" value.bind="projectDocument.test" />
        <select class="form-control" value.bind="projectDocument.projectFileType">
            <option>Select a Document Type</option>
            <option repeat.for="documentType of documentTypes" model.bind="documentType">${documentType.name}</option>
        </select>
    </td>
</tr>
import {computedFrom} from "aurelia-framework"
import {autoinject} from "aurelia-dependency-injection"

@autoinject
export class AddDocument {
    project = {};
    fileList: FileList;
    documentTypes = [
        { id: 1, name: "Blueprint" },
        { id: 2, name: "Shop Drawing" },
        { id: 3, name: "Proposal" },
        { id: 4, name: "Signed Proposal" }];

    constructor() {
    }

    @computedFrom("fileList")
    get projectDocumentItems(): ProjectDocumentItem[] {
        let files = [];
        if (!this.fileList) {
            return files;
        }

        for (let i = 0; i < this.fileList.length; i++) {
            let projectDocumentItem = new ProjectDocumentItem(this.fileList.item(i));
            projectDocumentItem.projectFileType = this.documentTypes[2];
            files.push(projectDocumentItem);
        }

        return files;
    }

    activate(params, routeConfig, navigationInstruction) {
        this.project = { Id: params.id };
    }

    upload() {
        console.log(this.projectDocumentItems);
    }

}

class ProjectDocumentItem {
    constructor(private file: File) {
    }

    test: string;

    projectFileType: {};
}

我为项目文档设置了一个test属性,名为test,用于测试绑定。未显示的是上传输入,它将接受多个文件并绑定到fileList属性。

计算projectDocumentItems getter并创建一堆ProjectDocumentItems,其中包含test和projectFileType属性。我设置了一个默认的projectFileType,并在表单中显示了正确的下拉值,但是当我更改它并查看projectDocumentItems属性值时,旧值仍然存在。

编辑: 要清楚,正在正确观察fileList属性,如果我选择多个文档,我会得到多个ProjectDocumentItems来循环。问题是,进行更改时未观察到ProjectDocumentItem属性。

表格的流程如下:

  1. 用户选择一个或多个要上传的文件。
  2. fileList属性更改。
  3. 计算projectDocumentItems getter。
  4. projectDocumentItems循环遍历fileList属性中的File对象,并创建新的ProjectDocumentItems并返回它们的数组。
  5. 视图已更新,列出了使用正确的文件属性值和在下拉列表中正确选择的documentType属性值创建的ProjectDocumentItem。
  6. 问题:问题是,如果我更改下拉列表并选择其他文档类型,或者如果我在绑定到ProjectDocumentItem.test的文本框中键入内容,则该值不会绑定回集合中的ProjectDocumentItem

1 个答案:

答案 0 :(得分:0)

这里的问题是@computedFrom无法监听数组。请尝试以下方法。

import { BindingEngine } from "aurelia-framework"
import { autoinject } from "aurelia-dependency-injection"

@autoinject
export class AddDocument {
    project = {};
    fileList: FileList;
    projectDocumentItems: ProjectDocumentItems[];

    subscriptions = [];

    documentTypes = [
        { id: 1, name: "Blueprint" },
        { id: 2, name: "Shop Drawing" },
        { id: 3, name: "Proposal" },
        { id: 4, name: "Signed Proposal" }];

    constructor(BindingEngine) {
        this.binding = BindingEngine;
    }

    activate(params, routeConfig, navigationInstruction) {
        this.project = { Id: params.id };
        this.projectDocumentItems = [];

        this.subscriptions.push(
            bindingEngine.collectionObserver(this.fileList)
                .subscribe((items) => 
                    items.forEach((item) => {
                        let projectDocumentItem = new ProjectDocumentItem(item);
                        projectDocumentItem.projectFileType = this.documentTypes[2];
                        this.projectDocumentItems.push(projectDocumentItem);
                    })
                )
        );
    }

    deactivate() {
        this.subscriptions.forEach((subscription) => subscription.dispose());
    }
}

itemsitem的定义可能存在一些问题,请仔细检查。此处提供的文档:http://aurelia.io/docs.html#/aurelia/binding/1.0.0-beta.1.1.3/doc/api/interface/CollectionObserver