Передача родителя, когда родительский компонент того же типа в Aurelia

Редактировать: этот вопрос раньше назывался "Получение родителя через DI, когда родительский тип в Aurelia того же типа", но из-за того, как мои элементы вложены, имеет смысл просто связать родительский элемент с элементом, поэтому заголовок был изменен чтобы отразить это.

Если у меня есть пользовательский элемент, Thing у которого есть ребенок Thing (у которого есть еще один ребенок Thingи т. д.), как я могу добавить родительский экземпляр, если класс один и тот же?

export class Thing {
    static inject = [Thing]; // <-- no reference to Thing as we are inside the class
    constructor(parentThing) {
        this.parent = parentThing;
    }
}

В качестве дополнительной сложности, корень Thing Элемент не будет иметь родителя, поэтому DI должен разрешать необязательную инъекцию.

3 ответа

Решение

Эта проблема не выглядит правильной или необходимой для использования DI. Если элемент должен получать какие-то определенные входные данные от своего потребителя, @bindable будет моим естественным первым взглядом. Так как насчет создания @bindable parentThing в Thing?

С другой стороны, если вы хотите получить доступ к родительскому контексту привязки, рассмотрите bind() жизненный цикл компонента.

Я не думаю, что ваша проблема может быть решена с помощью DI. Thing должен быть @transient если вы хотите иметь несколько экземпляров этого. Это означает, что контейнер не будет содержать ссылки на вещи, которые он создает.

Вот как это сделать: https://gist.run/?id=b075366d29f2400d3cc931f6fc26db24

app.html

<template>
  <require from="./thing"></require>

  <thing name="A">
    <thing name="B">
      <thing name="C">
        <thing name="D">
        </thing>
      </thing>
    </thing>
  </thing>
</template>

app.js

export class App {
}

факультативные-parent.js

import {resolver} from 'aurelia-dependency-injection';

@resolver()
export class OptionalParent {
  constructor(key) {
    this.key = key;
  }

  get(container) {
    if (container.parent && container.parent.hasResolver(this.key, false)) {
      return container.parent.get(this.key)
    }
    return null;
  }

  static of(key) {
    return new OptionalParent(key);
  }
}

thing.html

<template>
  <h3>
    My Name is "${name}".
    <span if.bind="parent">My parent's name is "${parent.name}".</span>
    <span if.bind="!parent">I don't have a parent.</span>
  </h3>
  <content></content>
</template>

thing.js

import {bindable, inject} from 'aurelia-framework';
import {OptionalParent} from './optional-parent';

@inject(OptionalParent.of(Thing))
export class Thing {
  @bindable name;

  constructor(parent) {
    this.parent = parent;
  }
}
Другие вопросы по тегам