Aurelia自定义元素从子视图模型访问数据到父视图模型

Aurelia自定义元素从子视图模型访问数据到父视图模型,aurelia,Aurelia,我是Aurelia的新手,需要帮助从另一个视图中的自定义元素访问值 我有一个场景,我想以多种形式共享附件的输入文件。我采用的方法之一是为输入文件创建自定义元素,这些文件可以在web应用程序中与多个表单共享 下面是我的代码: 名为FilePicker的自定义元素,将在多个表单之间共享。在我的请求页面中,我插入了名为: 我的要求是访问名为validFiles的属性,它是一个数组。我想将validFiles中的值用于Request视图模型中的自定义对象,该模型名为formData['attachme

我是Aurelia的新手,需要帮助从另一个视图中的自定义元素访问值

我有一个场景,我想以多种形式共享附件的输入文件。我采用的方法之一是为输入文件创建自定义元素,这些文件可以在web应用程序中与多个表单共享

下面是我的代码:

名为
FilePicker
的自定义元素,将在多个表单之间共享。在我的请求页面中,我插入了名为:

我的要求是访问名为
validFiles
的属性,它是一个数组。我想将
validFiles
中的值用于
Request
视图模型中的自定义对象,该模型名为
formData['attachment']

TS:

import { customElement, useView, bindable, bindingMode } from 'aurelia-framework';

@customElement('file-picker')
@useView('./file-picker.html')
export class FilePicker {

  @bindable accept = '';
  @bindable multiple = false;
  @bindable({ defaultBindingMode: bindingMode.twoWay }) files: FileList;

  validFiles = [];
  input: HTMLInputElement;


  // Validate function for on change event to input file.
  public filesChanged() {
    if (!this.files) {
      this.clearSelection();
    }
    if (this.files) {
      this.processFiles();
    }
  }

  // Trigger on button click
  public triggerInputClick() {
    this.input.click();
  }

  // Find value in array of object
  private findValinArrObj(arr, key, val) {
    return arr.map(function (v) { return v[key] }).indexOf(val);
  }

  // Process file for each new files uploaded via browser
  private processFiles() {
    if (this.files) {
      for (let i = 0; i < this.files.length; i++) {
        let findFile = this.findValinArrObj(this.validFiles, 'name', this.files.item(i).name);
        if (findFile === -1) {
          this.validFiles.push(this.files.item(i));
        }
      }
      this.clearSelection();
    }
  }

  // Remove file from  fileNames and validFiles array
  public removeByFileName(fileName) {
    if (this.validFiles) {
      for (let i = 0; i < this.validFiles.length; i++) {
        if (this.validFiles[i].name === fileName) {
          this.validFiles.splice(i, 1);
        }
      }
    }
  }

  // Clear input file in DOM
  private clearSelection() {
    this.input.type = '';
    this.input.type = 'file';
  }
}
<template>
  <input type="file" accept.bind="accept" multiple.bind="multiple"
         files.bind="files" ref="input"
         style="visibility: hidden; width: 0; height: 0;">
  <button class="btn btn-primary" click.delegate="triggerInputClick()">
    <slot>Browse...</slot>
  </button>
  <ul class="list-group" if.bind="validFiles">
    <li class="list-group-item" repeat.for="file of validFiles" style="padding: 0; border:none;">
      ${file.name} <span class="glyphicon glyphicon-remove text-danger" style="cursor: pointer;" click.delegate="removeByFileName(file.name)"></span>
    </li>
  </ul>
</template>
export class Request {
  pageTitle: string = "Request Page";
  title: string = '';
  description: string = '';
  businessValue: string = '';
  emails: string = '';
  formData: object = {};

  public postData() {
    this.formData['title'] = this.title;
    this.formData['description'] = this.description;
    this.formData['businessValue'] = this.businessValue;
    this.formData['emails'] = this.emails;
    this.formData['attachment'] = [];
    console.log(this.formData);
  }
}
<template>
  <require from="./request.css"></require>
  <require from="../../resources/elements/file-picker"></require>
  <div class="panel panel-primary">
    <div class="panel-heading">${pageTitle}</div>
    <div class="panel-body">
      <form class="form-horizontal">
        <div class="form-group">
          <label for="title" class="col-sm-2 control-label">Title</label>
          <div class="col-sm-10">
            <input type="text" value.two-way="title" class="form-control" id="title" placeholder="Brief one-line summary of the request">
          </div>
        </div>
        <div class="form-group">
          <label for="description" class="col-sm-2 control-label">Description</label>
          <div class="col-sm-10">
            <input type="text" value.two-way="description" class="form-control" id="description" placeholder="Detailed description of the request">
          </div>
        </div>
        <div class="form-group">
          <label for="description" class="col-sm-2 control-label">Business Value</label>
          <div class="col-sm-10">
            <input type="text" value.two-way="businessValue" class="form-control" id="description" placeholder="Description of how this offers business value">
          </div>
        </div>
        <div class="form-group">
          <label for="emails" class="col-sm-2 control-label">Email</label>
          <div class="col-sm-10">
            <input type="text" value.two-way="emails" class="form-control" id="emails" placeholder="Provide email address">
          </div>
        </div>
        <div class="form-group">
          <label for="exampleInputFile" class="col-sm-2 control-label">Attachment(s)</label>
          <div class="col-sm-10">
            <file-picker router.bind="router" accept="image/*" multiple="true" ></file-picker>
          </div>
        </div>

        <div class="form-group">
          <div class="col-sm-12">
            <button type="submit" class="btn btn-default pull-right" click.trigger="postData()">Submit</button>
          </div>
        </div>
      </form>
    </div>
  </div>
</template>
HTML:

import { customElement, useView, bindable, bindingMode } from 'aurelia-framework';

@customElement('file-picker')
@useView('./file-picker.html')
export class FilePicker {

  @bindable accept = '';
  @bindable multiple = false;
  @bindable({ defaultBindingMode: bindingMode.twoWay }) files: FileList;

  validFiles = [];
  input: HTMLInputElement;


  // Validate function for on change event to input file.
  public filesChanged() {
    if (!this.files) {
      this.clearSelection();
    }
    if (this.files) {
      this.processFiles();
    }
  }

  // Trigger on button click
  public triggerInputClick() {
    this.input.click();
  }

  // Find value in array of object
  private findValinArrObj(arr, key, val) {
    return arr.map(function (v) { return v[key] }).indexOf(val);
  }

  // Process file for each new files uploaded via browser
  private processFiles() {
    if (this.files) {
      for (let i = 0; i < this.files.length; i++) {
        let findFile = this.findValinArrObj(this.validFiles, 'name', this.files.item(i).name);
        if (findFile === -1) {
          this.validFiles.push(this.files.item(i));
        }
      }
      this.clearSelection();
    }
  }

  // Remove file from  fileNames and validFiles array
  public removeByFileName(fileName) {
    if (this.validFiles) {
      for (let i = 0; i < this.validFiles.length; i++) {
        if (this.validFiles[i].name === fileName) {
          this.validFiles.splice(i, 1);
        }
      }
    }
  }

  // Clear input file in DOM
  private clearSelection() {
    this.input.type = '';
    this.input.type = 'file';
  }
}
<template>
  <input type="file" accept.bind="accept" multiple.bind="multiple"
         files.bind="files" ref="input"
         style="visibility: hidden; width: 0; height: 0;">
  <button class="btn btn-primary" click.delegate="triggerInputClick()">
    <slot>Browse...</slot>
  </button>
  <ul class="list-group" if.bind="validFiles">
    <li class="list-group-item" repeat.for="file of validFiles" style="padding: 0; border:none;">
      ${file.name} <span class="glyphicon glyphicon-remove text-danger" style="cursor: pointer;" click.delegate="removeByFileName(file.name)"></span>
    </li>
  </ul>
</template>
export class Request {
  pageTitle: string = "Request Page";
  title: string = '';
  description: string = '';
  businessValue: string = '';
  emails: string = '';
  formData: object = {};

  public postData() {
    this.formData['title'] = this.title;
    this.formData['description'] = this.description;
    this.formData['businessValue'] = this.businessValue;
    this.formData['emails'] = this.emails;
    this.formData['attachment'] = [];
    console.log(this.formData);
  }
}
<template>
  <require from="./request.css"></require>
  <require from="../../resources/elements/file-picker"></require>
  <div class="panel panel-primary">
    <div class="panel-heading">${pageTitle}</div>
    <div class="panel-body">
      <form class="form-horizontal">
        <div class="form-group">
          <label for="title" class="col-sm-2 control-label">Title</label>
          <div class="col-sm-10">
            <input type="text" value.two-way="title" class="form-control" id="title" placeholder="Brief one-line summary of the request">
          </div>
        </div>
        <div class="form-group">
          <label for="description" class="col-sm-2 control-label">Description</label>
          <div class="col-sm-10">
            <input type="text" value.two-way="description" class="form-control" id="description" placeholder="Detailed description of the request">
          </div>
        </div>
        <div class="form-group">
          <label for="description" class="col-sm-2 control-label">Business Value</label>
          <div class="col-sm-10">
            <input type="text" value.two-way="businessValue" class="form-control" id="description" placeholder="Description of how this offers business value">
          </div>
        </div>
        <div class="form-group">
          <label for="emails" class="col-sm-2 control-label">Email</label>
          <div class="col-sm-10">
            <input type="text" value.two-way="emails" class="form-control" id="emails" placeholder="Provide email address">
          </div>
        </div>
        <div class="form-group">
          <label for="exampleInputFile" class="col-sm-2 control-label">Attachment(s)</label>
          <div class="col-sm-10">
            <file-picker router.bind="router" accept="image/*" multiple="true" ></file-picker>
          </div>
        </div>

        <div class="form-group">
          <div class="col-sm-12">
            <button type="submit" class="btn btn-default pull-right" click.trigger="postData()">Submit</button>
          </div>
        </div>
      </form>
    </div>
  </div>
</template>

${pageTitle}
标题
描述
商业价值
电子邮件
附件:
提交

非常感谢您的帮助。:)

您可以在
请求
视图上设置
双向
绑定,将子视图(
文件选择器
)中的
有效文件
绑定到父视图(
请求
)中的变量:

request.html:

<file-picker valid-files.two-way="validFiles"></file-picker>
file-picker.ts:

@bindable
public validFiles: File[];

这样,对子视图或父视图中的
有效文件
对象所做的任何更改都将更新两个视图模型中的对象。

您可以在
请求
视图上设置
双向
绑定,将子视图中的
有效文件
绑定到父视图中的变量(
请求
):

request.html:

<file-picker valid-files.two-way="validFiles"></file-picker>
file-picker.ts:

@bindable
public validFiles: File[];
这样,对子视图或父视图中的
validFiles
对象所做的任何更改都将更新两个viewmodels中的对象