绑定到动态生成的组件/元素的可绑定属性

我正在aurelia上开发一个自定义属性,以允许用户在输入文本区域时从列表中进行选择。例如,用法将是这样的:

<textarea value.bind="description" placeholder="your description here" auto-complete></textarea>

,并且您可能已经注意到,auto-complete是属性。现在,当我想显示提示时,我想在一个自定义元素中做到这一点以使其简单。因此,属性的附加方法将如下所示:

attached() {
    this.containerElement = document.createElement('div');
    this.containerElement.style.position = 'relative';
    const ce = document.createElement('autocomplete-menu');
    this.containerElement.appendChild(ce);
    const ceView = this.templatingEngine.enhance(ce);
    ceView.attached();
    const currentParrent = this.element.parentElement;
    currentParrent.replaceChild(this.containerElement,this.element);
    this.containerElement.appendChild(this.element);
}

现在它将打开并成功显示提示区域。屏幕截图:

绑定到动态生成的组件/元素的可绑定属性

当我想通过属性视图模型与生成的元素进行通信时,问题就开始了。例如,我想将数据发送到其视图模型或将某个对象绑定到该对象的可绑定属性。对于这个问题,我找到了以下解决方案:

绑定到动态生成的组件/元素的可绑定属性

https://discourse.aurelia.io/t/dynamically-add-custom-attribute-to-element/1400/6

,并阅读本文的最后一部分:

https://ilikekillnerds.com/2016/01/enhancing-at-will-using-aurelias-templating-engine-enhance-api/

并弄清楚,我必须为元素的视图模型引入一个对象作为bindingContext或overrideContext。因此,如果我是对的,我已经测试了以下解决方案:

this.containerElement.appendChild(ce);
let vm = { test: 1 }
const ceView = this.templatingEngine.enhance({ element: ce,bindingContext: vm });
ceView.addBinding(vm);
ceView.attached();

this.containerElement.appendChild(ce);
let vm = { test: 1 }
const ceView = this.templatingEngine.enhance(ce);
ceView.bind(vm);
ceView.attached();
console.log(ceView);

但是在元素的附加生命周期挂钩上,我记录了视图模型,并注意到this上没有bindingContext属性。

现在有两个问题:

  1. 上述解决方案有什么问题,如何将此类数据发送到增强型元素?
  2. 是否有办法使用bindable s的已知方法来做到这一点?我的意思是在元素视图模型上定义一个可绑定属性,并在增强方法完成后绑定到该属性。而不是使用bindingContext和overrideContext?
wzq185833229 回答:绑定到动态生成的组件/元素的可绑定属性

幸运的是,问题已解决。解决方案不是那么复杂,而是1.对我来说非常有用(我将在下面描述)2.由于缺少aurelia文档,因此很难解决这个简单的问题。

问题在于我误解了bindingContext和container的含义。我当时以为bindingContext将引用子元素的视图模型,并且我必须将其容器指向父上下文(即属性)。但是我发现我应该将bindingContext指向属性的上下文。我对这两个含义仍然不甚了解,但是解决方案像以下示例一样简单而优美:

this.containerElement = document.createElement('div');
this.containerElement.style.position = 'relative';
this.containerElement.style.display = 'flex';
this.containerElement.style.flexDirection = 'row-reverse';
this.ce = document.createElement('autocomplete-menu');
this.ce.setAttribute('filter.bind','filter');
this.ce.setAttribute('show.bind','showMentionPicker');
this.ce.setAttribute('parent-height','${element.clientHeight}px');
this.ce.setAttribute('view-model.ref','mentionPickerViewModel');
this.ce.setAttribute('on-select.call','complete(mentionPickerViewModel.getRemainingOfHint())');
const ceView = this.templatingEngine.enhance({ element: this.ce,container: this.container });
ceView.bind(this);
ceView.attached();
this.containerElement.appendChild(this.ce);
const currentParrent = this.element.parentElement;
currentParrent.replaceChild(this.containerElement,this.element);
this.containerElement.appendChild(this.element);

并且绑定引用的是具有以下属性的属性的this上下文:

filter = '';
showMentionPicker = false;
mentionPickerViewModel; 

如果样本不足以解决您的问题,请问我更多信息。

本文链接:https://www.f2er.com/2867716.html

大家都在问