我正在尝试使用 aurelia-validation 插件对表单执行验证。我正在创建一个自定义验证渲染器,它将更改输入框的颜色并在框旁边放置一个图标。单击或悬停该图标时,会出现一条弹出消息,其中显示实际的错误消息。
目前,我正在渲染器中手动渲染代码中的所有内容,但似乎最好将所有这些内容的 html 定义在 html 文件中,并与关联的 js 文件一起处理单击和悬停图标。 IOW,将所有错误内容(带有弹出窗口的图标)封装在 View/ViewModel 中,然后封装在render()
我的验证渲染器,不知何故只是在有问题的元素之后编写一个新的实例。
这可以吗?我已经看到如何使用<compose></compose>
元素,但我确实试图避免将其添加到我的所有表单的输入框中。
这是我当前渲染器中的内容:
import {ValidationError, RenderInstruction} from 'aurelia-validation'
export class IconValidationRenderer {
render(instruction){
//Unrender old errors
for(let {result, elements} of instruction.unrender){
for(let element of elements){
this.remove(element, result);
}
}
//Render new errors
for(let {result, elements} of instruction.render){
for(let element of elements){
this.add(element, result)
}
}
}
add(element, result){
if(result.valid)
return
//See if error element already exists
if(element.className.indexOf("has-error") < 0){
let errorIcon = document.createElement("i")
errorIcon.className = "fa fa-exclamation-circle"
errorIcon.style.color = "darkred"
errorIcon.style.paddingLeft = "5px"
errorIcon.id = `error-icon-${result.id}`
errorIcon.click = ""
element.parentNode.appendChild(errorIcon)
element.classList.add("has-error")
element.parentNode.style.alignItems = "center"
let errorpop = document.createElement("div")
let errorarrow = document.createElement("div")
let errorbody = document.createElement("div")
errorpop.id = `error-pop-${result.id}`
errorpop.className = "flex-row errorpop"
errorarrow.className = "poparrow"
errorbody.className = "flex-col popmessages"
errorbody.innerText = result.message
console.log("Computing position")
let elemRec = errorIcon.getBoundingClientRect()
let elemH = errorIcon.clientHeight
errorpop.style.top = elemRec.top - 10 + "px"
errorpop.style.left = elemRec.right + "px"
errorpop.appendChild(errorarrow)
errorpop.appendChild(errorbody)
element.parentNode.appendChild(errorpop)
}
}
remove(element, result){
if(result.valid)
return
element.classList.remove("has-error")
let errorIcon = element.parentNode
.querySelector(`#error-icon-${result.id}`)
if(errorIcon)
element.parentNode.removeChild(errorIcon)
//Need to remove validation popup element
}
}
谢谢你尽你所能的帮助。
附:此时,我没有像我提到的那样实现单击或悬停 - 这是我想做的事情,但我什至不确定此时如何实现。如果我可以编写一个虚拟机,那就更直接了。
EDIT
我被指着this https://ilikekillnerds.com/2016/01/enhancing-at-will-using-aurelias-templating-engine-enhance-api/Aurelia Gitter 频道上某人的文章。我尝试过实现 TemplateEngine,但显然我没有以正确的方式实现它。这就是我所拥有的。
添加人员对话框.js//具有经过验证的表单的VM
import {TemplatingEngine,NewInstance} from 'aurelia-framework'
import {ValidationController} from 'aurelia-validation'
import {IconValidationRenderer} from './resources/validation/icon-validation-renderer'
export class AddPersonDialog {
static inject = [NewInstance.of(ValidationController),TemplatingEngine]
constructor(vc, te){
this.vc = vc
this.vc.addRenderer(new IconValidationRenderer(te))
}
图标验证renderer.js
//Plus all the other bits that I posted in the code above
constructor(te){
this.te = te
}
add(element, result){
if(result.valid) return
if(element.className.indexOf("has-error") < 0 {
//replaced there error icon code above with this (as well as a few different variations
let test = document.createElement("field-error-info")
element.parentNode.appendChild(test)
this.te.enhance({element: test})
}
}
字段错误信息.html
<template>
<require from="./field-error-info.css" ></require>
<i class="fa fa-exclamation-circle" click.delegate="displayMessage = !displayMessage" mouseenter.delegate="displayMessage = true" mouseleave.delegate="displayMessage = false"></i>
<div show.bind="displayMessage" class="flex-row errorpop" style="left:300px">
<div class="poparrow"></div>
<div class="flexcol popmessages">Message 1</div>
</div>
</template>
最终,<field-error-info></field-error-info>
被添加到 DOM 但实际上并没有被渲染。 (顺便说一句,我也尝试添加<require from='./elements/field-error-info'></require>
在 add-person-dialog.html 中。