Aurelia: доступ к родительскому методу VM из дочерней виртуальной машины

Обычный пример использования со списками - это доступ к методу списка из элемента списка. Например: у элемента проекта есть возможность удалить себя из содержащего списка. Я хотел бы знать, является ли шаблон, который я описываю ниже для Aurelia, действителен или, может быть, есть лучшие решения.

В Aurelia у меня есть следующая настройка:

Содержит список: (project-list.html и projectList.js)

<template>      
  <div class="projects">
    <input value.bind="newProjectName" placeholder="New project name"/>
    <project-item repeat.for="project of projects" project.bind="project"></project-item>
  </div>
</template>

и дочерний элемент: (project-item и projectItem.js)

<template>
  <span class="title">
    ${project.name} <i click.delegate="deleteProject(project)" class="icon-trash"></i>
  </span>
</template>

В этом случае deleteProject(project) является членом VMList projectList:

function deleteProject(project){
    var index = this.projects.indexOf(project);
    if (index>-1){
        this.projects.splice(index,1)
    }
}

К сожалению, как я понимаю из этого вопроса https://github.com/aurelia/framework/issues/311, что wil не работает (больше).

В качестве рабочего процесса я могу привязать функцию к VM элемента проекта:

@bindable delete: Function;

и в шаблоне списка проектов:

<project-item repeat.for="project of projects" project.bind="project" delete.bind="deleteProject"></project-item>

Это работает, предоставление связанной функции является назначенным свойством с закрытием:

deleteProject = function(project : Projects.Project){
        var index = this.projects.indexOf(project);
        if (index>-1){
            _.remove(this.projects,(v,i)=>i==index);
        }
    }

Закрытие необходимо для доступа к правильному контексту (this, являющийся списком проектов). Использование

function deleteProject(project)

this будет ссылаться на контекст элемента проекта.

Несмотря на то, что эта конструкция работает и не имеет больших накладных расходов в сантехнике, мне кажется немного хрупкой:

  • Назначенная функция трудно отличить форму от обычной функции класса
  • связывание функции, а также элемент списка кажется немного "переутомленным".

Или, может быть, мне не хватает механизма барботирования Aurelia, который обеспечивает доступ к родительской виртуальной машине, обрабатываемой каркасом?

Изменить после ответа: Основываясь на ответе @Sylvain, я создал GistRun, который реализует скелетный список и реализацию списка элементов с добавлением и удалением:

Реализация списка списка Aurelia Skeleton

Ответ 1

Вот несколько альтернатив передаче ссылки на функцию:

  • Передайте дочерний компонент публичное событие с использованием экземпляра EventAggregator singleton и ответьте родительский компонент на событие

  • Попросите дочерний компонент передать частное событие с помощью частного экземпляра EventAggregator и ответьте родительский компонент на событие

  • Попросите дочерний компонент передать событие DOM и привязать его к родительскому объекту с помощью delete.call, как этот <project-item repeat.for="project of projects" project.bind="project" delete.call="deleteProject($even t)"></project-item>

Мое личное предпочтение - это третий вариант. Это больше похоже на "веб-компоненты".