Aurelia: доступ к родительскому методу VM из дочерней 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)
является членом projectList VM:
function deleteProject(project){
var index = this.projects.indexOf(project);
if (index>-1){
this.projects.splice(index,1)
}
}
к сожалению, как я понимаю из этого вопроса https://github.com/aurelia/framework/issues/311, это не сработает (больше).
в качестве обходного пути я могу связать функцию на project-item 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, который реализует скелет списка и реализации элемента списка с add и remove:
1 ответов
вот несколько альтернатив передаче ссылки на функцию:
попросите дочерний компонент транслировать публичное событие с помощью
EventAggregator
экземпляр singleton и родительский компонент реагируют на событиепусть дочерний компонент транслирует частное событие с помощью private
EventAggregator
экземпляр и родительский компонент реагируют на событиечтобы дочерний компонент транслировал событие DOM и свяжите его с родителем с помощью
delete.call
такой<project-item repeat.for="project of projects" project.bind="project" delete.call="deleteProject($even t)"></project-item>
мое личное предпочтение-третий вариант. Для меня это больше похоже на "веб-компоненты".