通用 Aurelia 对话框需要在脏和有效时启用保存
Generic Aurelia dialog needs Save enabled when dirty and valid
我正在尝试制作一个通用的、可重复使用的对话框,我们可以将其用于简单对象的基本数据输入——phone、电子邮件等
一般来说,我有一个助手 class 打开对话框,一个使用 aurelia-dialog 的通用对话框,然后是一个虚拟机,它被组合到包含所有表单编辑的主体的通用对话框中代码。
我遇到的问题是按钮在页脚中,它是对话框 vm 的一部分,但验证和脏指示器存在于构成正文的 vm 中。我想 disable/enable 基于正文 vm 中的指示器的保存按钮(在页脚中)。
对话框助手:
import {DialogService} from 'aurelia-dialog'
import {EditDialog} from 'app/resources/dialogs/edit-dialog'
export class DialogHelper {
static inject = [DialogService]
constructor(dialogService){
this.dialogService = dialogService
}
edit(title, view, item, showDelete){
return this.dialogService.open({
viewModel: EditDialog,
model: {view: view,
item: item,
title: title,
showDelete: showDelete } })
}
}
调用代码:
let email = {emailAddress: "123@gmail.com", emailType: "Personal"}
this.dialogHelper.edit("Email",'./pages/email-dialog',email,false)
EditDialog.js
import {DialogController} from 'aurelia-dialog'
export class EditDialog {
static inject = [DialogController]
showDelete = false
constructor(dialogController){
this.dialogController = dialogController
}
activate(options){
this.options = options
}
EditDialog.html
<template>
<ai-dialog>
<ai-dialog-header style="display:flex; justify-content:space-between">
<span>Add/Edit ${options.title}</span><i style="cursor:pointer" class="fa fa-close" click.delegate="dialogController.cancel()"></i>
</ai-dialog-header>
<ai-dialog-body>
<compose view-model.bind="options.view" model.bind="options.item" ></compose>
</ai-dialog-body>
<ai-dialog-footer style="display:flex;justify-content:space-between;">
<span>
<!--Should have an if.bind here but not sure how since vm composed above knows details -->
<button click.delegate="dialogController.ok({type:'save'})">Save</button>
<button click.delegate="dialogController.cancel()">Cancel</button>
</span>
<button if.bind="options.showDelete" click.delegate="dialogController.ok({type:'delete'})"><i class="fa fa-trash"></i></button>
</ai-dialog-footer>
</ai-dialog>
</template>
邮箱-dialog.js
import {ValidationRules, ValidationController} from 'aurelia-validation'
import {computedFrom,NewInstance} from 'aurelia-framework'
export class EmailDialog {
static inject = [NewInstance.of(ValidationController)]
email = null
constructor(validationController){
this.validationController = validationController
this.rule = ValidationRules.ensure(i => i.emailAddress)
.required()
.email()
.ensure(i => i.emailType)
.required()
.rules
}
activate(item){
this.original = item
this.email = JSON.parse(JSON.stringify(item))
}
@computedFrom('email.emailAddress', 'email.emailType')
get canSave() {
for(var prop in this.original){
if(this.email[prop] != this.original[prop])
return false
}
return true
}
}
我是否必须使用 EventAggregator 将消息传递给父级,或者是否有更好的方法通过某种绑定来处理这个问题? (或者是否有更好的方法一起解决这个问题?)
感谢您的帮助!
我不确定这是否适用于 aurelia-dialog,但这是我的建议:
您可以使用 view-model.ref="someIdentifier"
属性来获取 <compose>
元素的 view-model 的引用。 Cheat Sheet
此引用应该是 Compose
class 和包含实际视图模型实例的 currentViewModel
属性(例如 EmailDialog
)。
这是一个简化的要点示例:https://gist.run/?id=b23bf709d98b3bd3ae427852f104c890
将其应用于您的案例:
<ai-dialog-body>
<compose view-model.ref="customVM" view-model.bind="options.view" model.bind="options.item" ></compose>
</ai-dialog-body>
<ai-dialog-footer style="display:flex;justify-content:space-between;">
<span>
<button if.bind="customVM.currentViewModel.canSave" click.delegate="dialogController.ok({type:'save'})">Save</button>
<button click.delegate="dialogController.cancel()">Cancel</button>
</span>
<button if.bind="options.showDelete" click.delegate="dialogController.ok({type:'delete'})"><i class="fa fa-trash"></i></button>
</ai-dialog-footer>
我正在尝试制作一个通用的、可重复使用的对话框,我们可以将其用于简单对象的基本数据输入——phone、电子邮件等
一般来说,我有一个助手 class 打开对话框,一个使用 aurelia-dialog 的通用对话框,然后是一个虚拟机,它被组合到包含所有表单编辑的主体的通用对话框中代码。
我遇到的问题是按钮在页脚中,它是对话框 vm 的一部分,但验证和脏指示器存在于构成正文的 vm 中。我想 disable/enable 基于正文 vm 中的指示器的保存按钮(在页脚中)。
对话框助手:
import {DialogService} from 'aurelia-dialog'
import {EditDialog} from 'app/resources/dialogs/edit-dialog'
export class DialogHelper {
static inject = [DialogService]
constructor(dialogService){
this.dialogService = dialogService
}
edit(title, view, item, showDelete){
return this.dialogService.open({
viewModel: EditDialog,
model: {view: view,
item: item,
title: title,
showDelete: showDelete } })
}
}
调用代码:
let email = {emailAddress: "123@gmail.com", emailType: "Personal"}
this.dialogHelper.edit("Email",'./pages/email-dialog',email,false)
EditDialog.js
import {DialogController} from 'aurelia-dialog'
export class EditDialog {
static inject = [DialogController]
showDelete = false
constructor(dialogController){
this.dialogController = dialogController
}
activate(options){
this.options = options
}
EditDialog.html
<template>
<ai-dialog>
<ai-dialog-header style="display:flex; justify-content:space-between">
<span>Add/Edit ${options.title}</span><i style="cursor:pointer" class="fa fa-close" click.delegate="dialogController.cancel()"></i>
</ai-dialog-header>
<ai-dialog-body>
<compose view-model.bind="options.view" model.bind="options.item" ></compose>
</ai-dialog-body>
<ai-dialog-footer style="display:flex;justify-content:space-between;">
<span>
<!--Should have an if.bind here but not sure how since vm composed above knows details -->
<button click.delegate="dialogController.ok({type:'save'})">Save</button>
<button click.delegate="dialogController.cancel()">Cancel</button>
</span>
<button if.bind="options.showDelete" click.delegate="dialogController.ok({type:'delete'})"><i class="fa fa-trash"></i></button>
</ai-dialog-footer>
</ai-dialog>
</template>
邮箱-dialog.js
import {ValidationRules, ValidationController} from 'aurelia-validation'
import {computedFrom,NewInstance} from 'aurelia-framework'
export class EmailDialog {
static inject = [NewInstance.of(ValidationController)]
email = null
constructor(validationController){
this.validationController = validationController
this.rule = ValidationRules.ensure(i => i.emailAddress)
.required()
.email()
.ensure(i => i.emailType)
.required()
.rules
}
activate(item){
this.original = item
this.email = JSON.parse(JSON.stringify(item))
}
@computedFrom('email.emailAddress', 'email.emailType')
get canSave() {
for(var prop in this.original){
if(this.email[prop] != this.original[prop])
return false
}
return true
}
}
我是否必须使用 EventAggregator 将消息传递给父级,或者是否有更好的方法通过某种绑定来处理这个问题? (或者是否有更好的方法一起解决这个问题?)
感谢您的帮助!
我不确定这是否适用于 aurelia-dialog,但这是我的建议:
您可以使用 view-model.ref="someIdentifier"
属性来获取 <compose>
元素的 view-model 的引用。 Cheat Sheet
此引用应该是 Compose
class 和包含实际视图模型实例的 currentViewModel
属性(例如 EmailDialog
)。
这是一个简化的要点示例:https://gist.run/?id=b23bf709d98b3bd3ae427852f104c890
将其应用于您的案例:
<ai-dialog-body>
<compose view-model.ref="customVM" view-model.bind="options.view" model.bind="options.item" ></compose>
</ai-dialog-body>
<ai-dialog-footer style="display:flex;justify-content:space-between;">
<span>
<button if.bind="customVM.currentViewModel.canSave" click.delegate="dialogController.ok({type:'save'})">Save</button>
<button click.delegate="dialogController.cancel()">Cancel</button>
</span>
<button if.bind="options.showDelete" click.delegate="dialogController.ok({type:'delete'})"><i class="fa fa-trash"></i></button>
</ai-dialog-footer>