Aurelia,自定义元素上的一长串可绑定项。重构?

Aurelia, long list of bindables on custom element. Refactor?

我有一个重复的卡片类型自定义元素,它绑定到从 api 中提取的 JSON 数据。我当前创建数据并将其绑定到这些显示的卡片的方法有效,但关于它的一切都让我尖叫 "REFACTOR"。有没有更好的方法来使用 Aurelia 实现这些目标?

我当前的自定义元素模式如下所示

pager-view.html

  <!-- Loop through the JSON task-data (each card contains the chosen task-data to display) -->
  <template repeat.for="task of pageData[currentPage - 1]">

    <!--Bind each tasks data to a card as we loop-->
    <card-commit

      task-data.bind="task"
      task-id.bind="task.ID"
      task-name.bind="task.name"
      project-id.bind="task.project.ID"
      project-name.bind="task.project.name"
      assigned-to.bind="task.assignedTo.name"
      successors.bind="task.successors"
      commit-status.bind="task.commitStatus"
      planned-start-date.bind="task.plannedStartDate"
      planned-comp-date.bind="task.plannedCompletionDate"
      duration.bind="task.duration"
      actual-start-date.bind="task.actualStartDate"
      commit-date.bind="task.commitDate"
      condition.bind="task.condition"
      constraint.bind="task.taskConstraint"
      constraint-date.bind="task.constraintDate"
      status.bind="task.status"
      note.bind="task.lastNote"
      note-text.bind="task.lastNote.noteText"
      note-entry-date.bind="task.lastNote.entryDate"
      note-avatar-download-url.bind="task.lastNote.owner.avatarDownloadURL"
      note-owner-name.bind="task.lastNote.owner.name"
      actual-completion-date.bind="task.actualCompletionDate"
    ></card-commit>

  </template>

卡-commit.ts

import {bindable, inject} from 'aurelia-framework';

export class CardCommit {
  @bindable public taskData;
  @bindable public taskId;
  @bindable public taskName;
  @bindable public projectId;
  @bindable public projectName;
  @bindable public assignedTo;
  @bindable public successors;
  @bindable public commitStatus;
  @bindable public plannedStartDate;
  @bindable public plannedCompDate;
  @bindable public duration;
  @bindable public actualStartDate;
  @bindable public actualStartDelta;
  @bindable public commitDate;
  @bindable public condition;
  @bindable public conditionClass;
  @bindable public conditionText;
  @bindable public constraint;
  @bindable public constraintDate;
  @bindable public status;
  @bindable public note;
  @bindable public noteText;
  @bindable public noteEntryDate;
  @bindable public noteAvatarDownloadUrl;
  @bindable public noteOwnerName;
  @bindable public updateNoteText;
  @bindable public actualCompletionDate;

  constructor() {
    // ... do constructor stuff
  }

  // ... other methods etc
}

卡-commit.html

<!-- Do all sorts of stuff with the bound data, for example... -->
<template>
  <!-- This example wouldn't really work, just demonstrating how I'm using the bound data -->
  <article data-task-id="${ taskId }">
    <ul repeat.bind="for example of task">
      <li data-example-commit="example.commitDate">${example.condition}</li>
    </ul>
  </article>
</template>

也许我太挑剔了,但如果我觉得我应该能够在 至少 中以更紧凑的方式定义这种关系,特别是长列表绑定被(本质上)定义了两次。但我只是不确定我还能如何实现这一目标,并且在 subject/issue 上并没有真正找到很多具体的东西。

  • 您可以将对象绑定到 class 属性(就像我在 pager-view.html 中对 task-data.bind="task" 所做的那样)

  • 使用此对象直接在模板中引用您想要的内容。

所以修改后会是这样的...

pager-view.html

  <!-- Loop through the JSON task-data (each card contains the chosen task-data to display) -->
  <template repeat.for="task of pageData[currentPage - 1]">

    <!--Bind each tasks data to a card as we loop-->
    <card-commit
      task-data.bind="task"
    ></card-commit>

  </template>

卡-commit.ts

import {bindable, inject} from 'aurelia-framework';

export class CardCommit {
  @bindable public taskData;

  constructor() {
    // ... do constructor stuff
  }

  // ... other methods etc
}

卡-commit.html

<!-- Now we reference the data that we want directly on the `taskData` attribute -->
<!-- Do all sorts of stuff with the bound data, for example... -->
<template>
  <!-- This example wouldn't really work, just demonstrating how I'm using the bound data -->
  <article data-task-id="${ taskData.taskId }">
    <ul repeat.bind="for example of taskData.task">
      <li data-example-commit="example.commitDate">${example.condition}</li>
    </ul>
  </article>
</template>

然而,(也许这是可能的,但我找不到任何参考资料),真的 很高兴能够 inject/pass taskData 到 class 构造函数,有点像这样...

pager-view.html

<!--Bind each tasks data to a card as we loop-->
<card-commit
  card-commit.constructor="task"
></card-commit>

然后可以在class的构造函数中合并它,也许是这样的:

卡-commit.ts

import {bindable, inject} from 'aurelia-framework';

export class CardCommit {
  @bindable public taskData;

  constructor(taskData) {
    Object.entries(taskData).forEach(([key, val]) => {
       Object.assign(this, {[key]: val});
    });
  }

  // ... other methods etc
}

然后我们可以直接访问对象的属性,就像在为重构提供的初始代码中一样。

如果我有时间找到完成此操作的方法,我会进行更新。同时,如果其他人知道该怎么做,我很乐意接受它作为代替这个的答案。