Con*_*ver 5 data-binding template-engine aurelia
我正在 aurelia 上开发一个自定义属性,以便用户在输入文本区域时从列表中进行选择。例如,用法将是这样的:
<textarea value.bind="description" placeholder="your description here" auto-complete></textarea>
Run Code Online (Sandbox Code Playgroud)
正如您可能注意到的, theauto-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);
}
Run Code Online (Sandbox Code Playgroud)
现在它打开并成功显示提示区域。屏幕截图:
当我想从属性视图模型生成的元素进行通信时,问题就开始了。例如,我想将数据发送到其视图模型或将某个对象绑定到该对象的可绑定属性。对于这个问题我找到了这些解决方案:
https://discourse.aurelia.io/t/dynamically-add-custom-attribute-to-element/1400/6 https://ilikekillnerds.com/2016/01/enhancing-at-will-using-aurelias-templated -引擎增强-api/
并阅读本文的最后一部分:
https://aurelia.io/docs/binding/how-it-works#abstract-syntax-tree
并发现,我必须为元素的视图模型引入一个对象作为其绑定上下文或覆盖上下文。因此,如果我是对的,我已经测试了以下解决方案:
this.containerElement.appendChild(ce);
let vm = { test: 1 }
const ceView = this.templatingEngine.enhance({ element: ce, bindingContext: vm });
ceView.addBinding(vm);
ceView.attached();
Run Code Online (Sandbox Code Playgroud)
和
this.containerElement.appendChild(ce);
let vm = { test: 1 }
const ceView = this.templatingEngine.enhance(ce);
ceView.bind(vm);
ceView.attached();
console.log(ceView);
Run Code Online (Sandbox Code Playgroud)
但在元素附加的生命周期挂钩上,我记录了视图模型并注意到 BindingContext 属性不存在this.
现在有两个问题:
bindable?我的意思是在元素视图模型上定义一个可绑定属性,并在增强方法完成后绑定到它。而不是使用 bindingContext 和 overrideContext?幸运的是问题已经解决了。解决方案并不是那么复杂,但是 1. 它对我来说非常有用(正如我接下来将描述的) 2. 由于缺乏 aurelia 文档,这个简单的问题很难解决。
问题是我误解了 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);
Run Code Online (Sandbox Code Playgroud)
并且绑定引用属性的 this 上下文,它具有以下属性:
filter = '';
showMentionPicker = false;
mentionPickerViewModel;
Run Code Online (Sandbox Code Playgroud)
如果示例不足以解决您的问题,请向我询问更多信息。