Для общего диалогового окна Aurelia необходимо, чтобы функция Save была включена, когда она грязная и действительная

Я пытаюсь создать общий, многократно используемый диалог, который мы можем использовать для ввода основных данных о простых объектах - телефоне, электронной почте и т. Д.

В общем, у меня есть вспомогательный класс, который открывает диалоговое окно, общий диалог с использованием aurelia-dialog, а затем виртуальный компьютер, который встраивается в общий диалог для тела, включающего весь код редактирования формы.

У меня проблема в том, что кнопки находятся в нижнем колонтитуле, который является частью диалога vm, но в vm, который составляет тело, есть индикатор проверки и грязный. Хочу отключить / включить кнопку Сохранить (в нижнем колонтитуле) исходя из индикаторов в теле 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 для передачи сообщений родителю или есть лучший способ справиться с этим через какое-то связывание? (Или есть просто лучший способ подойти к этой проблеме все вместе?)

Спасибо за вашу помощь!

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>
Другие вопросы по тегам