Aurelia - Как получить экземпляр динамически созданного пользовательского элемента в View / ViewSlot - PullRequest
2 голосов
/ 20 февраля 2020

Итак, я обнаружил, как динамически создавать и создавать пользовательский элемент Aurelia через слот просмотра / просмотра с помощью приведенного ниже кода, однако я не знаю, как получить его экземпляр (ну, я нашел способ, но он уродлив)

Вот служба утилит, которую я должен динамически создать пользовательский элемент

export class AureliaUtilService {
  constructor(
    private container: Container,
    private viewCompiler: ViewCompiler,
    private viewResources: ViewResources,
  ) { }

  createAureliaViewModelAddToSlot(templateUrl: string, bindableData: any, targetElement?: HTMLElement | Element, clearTargetContent = false): AureliaViewOutput | null {
    const viewFactory = this.viewCompiler.compile('<template><compose view-model.bind="template"></compose></template>', this.viewResources);

    if (targetElement) {
      if (clearTargetContent && targetElement.innerHTML) {
        targetElement.innerHTML = '';
      }

      // Creates a view
      const view = viewFactory.create(this.container);
      const bindings: any = { template: (templateUrl || ''), ...bindableData };

      view.bind(bindings, createOverrideContext(bindings));

      // Add the view to the slot
      const viewSlot = new ViewSlot(targetElement, true);
      if (viewSlot && viewSlot.add) {
        viewSlot.add(view);
      }
      return { view, viewSlot };
    }
    return null;
  }
}

, затем я называю его так, и мой пользовательский элемент отображается на экране, yay

const targetElm = document.querySelector('.container');
const templateUrl = PLATFORM.moduleName('custom-element');
const bindings = { collection: this.collection };
const dynamicElement = this.aureliaUtilService.createAureliaViewModelAddToSlot(templateUrl, bindings, targetElm, true);

но теперь мне нужно и нужно изменить некоторые свойства этого пользовательского элемента, как я могу получить его экземпляр? Записав объект в консоль, я вроде нашел экземпляр, углубившись (действительно, глубоко), но это уродливо, поэтому должен быть лучший способ !?

Вот уродливый способ глубокого погружения, который я нашел.

// first I somehow need to wait the dynamically created Custom Element to fully rendered
// for that I found that I can wrap it in a setTimeout for a full lifecycle to pass
const instance = dynamicElement.view.children[0].children[0].container.viewModel;

// now I can change any of its properties
instance.selectedId = 123;

// I also need to watch for a property changes
// I found that I can do it this way
instance.selectedItemChanged = (item => console.log('item changed', item));

Так что да, это работает, но должен быть лучший способ ... верно?

...