1

我正在尝试制作一个通用的、可重用的对话框,我们可以将其用于简单对象(电话、电子邮件等)的基本数据输入。

一般来说,我有一个打开对话框的帮助类,一个使用 aurelia-dialog 的通用对话框,然后是一个 vm,它被组合到包含所有表单编辑代码的主体的通用对话框中。

我遇到的问题是按钮位于作为对话框虚拟机一部分的页脚中,但验证和脏指示符存在于组成正文的虚拟机中。我想根据 body 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)

编辑对话框.js

import {DialogController} from 'aurelia-dialog'

export class EditDialog {
   static inject = [DialogController]

   showDelete = false

   constructor(dialogController){
        this.dialogController = dialogController
   }

   activate(options){
       this.options = options
   }

编辑对话框.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 将消息传递给父级,或者是否有更好的方法通过某种绑定来处理?(或者有没有更好的方法来解决这个问题?)

谢谢你的帮助!

4

1 回答 1

1

我不完全确定这是否适用于 aurelia-dialog,但这是我的建议:

您可以使用view-model.ref="someIdentifier"属性来获取<compose>元素视图模型的引用。备忘单

该引用应该是一个Compose具有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>
于 2017-01-13T16:11:35.943 回答