简体   繁体   中英

Use aurelia-dialog with bootstrap, semantic, or other ui kit

I'm using semantic-ui, which has its own modal functionality built in ( see here ). Rather than writing all the code to leverage this particular functionality in Aurelia, is there a way to hook into the aurelia-dialog plugin's rendering pipeline so I can use configure the aurelia-dialog plugin to use semantic-ui?

Yes, there is.

Aurelia-dialog provides an abstract Renderer interface, which it uses to interface with a renderer. By default, it'll use the renderer that it provides, but you can override this by configuring the dialog plugin, like so:

import {MyRenderer} from './my-renderer';

aurelia.use.plugin('aurelia-dialog', (config) => {
    config.useRenderer(MyRenderer);
});

...where MyRenderer uses the abstract Renderer interface . In your renderer, you'll need to implement three methods: getDialogContainer , showDialog , and hideDialog .

Some caveats - in your showDialog function, you will need to create showDialog and hideDialog methods and attach them to the dialogController that is passed as an argument. This ensures that your dialogController can programmatically close the dialog.

After you've implemented and registered your renderer, the dialog plugin will then use the UI toolkit you've chosen. Hope this helps.

This is my solution(in TypeScript) for semantic-ui modals, it does not use aurelia-dialog.

The view (/ui/dialogs/dialog-confirm.html):

<template>
    <div class="ui modal small" ref="dialogElement">
        <div class="header">${model.headerText}</div>
        <div class="content">
            <p>${model.messageText}</p>
        </div>
        <div class="actions">
            <div class="ui approve button">${model.confirmText?model.confirmText:'OK'}</div>
            <div class="ui cancel button">${model.cancelText?model.cancelText:'Cancel'}</div>
        </div>
    </div>
</template>

The view-model (/ui/dialogs/dialog-confirm.ts):

export class Dialog {
    model;
    done;
    result;
    dialogElement:HTMLElement;
    activate(data) {
        if( data ){
            this.model = data.model;
            this.done = data.done;
            this.result = false;
        }
    }
    bind(){
        $(this.dialogElement)
            .modal({
                onApprove : ()=>{ this.result = true; },
                onDeny : ()=>{ this.result = false; },
                onHide : ()=>{ this.done(this.result); }
            })
            .modal('show');
    }
}

The Dialog class (/ui/dialogs/dialog.ts):

import { inject } from 'aurelia-framework';
import { EventAggregator } from 'aurelia-event-aggregator';

@inject(EventAggregator)
export class Dialog {
    constructor(private eventAggregator) {
    }
    show(viewName: string, model) {
        return new Promise( (resolve, reject) => {
            this.eventAggregator.publish('showDialog', { 
                viewName: viewName,
                model: model,
                resolve: resolve
            });
        });
    }
}

... inject EventAggregator into your App class and add this to the attached() hook:

attached() {
    this.eventAggregator.subscribe('showDialog', (event) => {
        console.assert( !this.dialogData, "Only one dialog can be shown at any time." );
        event.done = (result) => {
            event.resolve(result);
            this.dialogData = null;
        }
        this.dialogName = event.viewName;
        this.dialogData = event;
    });
}

... finally add this to your app.html:

<compose if.bind="dialogData" view-model="./ui/dialogs/${dialogName}" model.bind="dialogData" view="./ui/dialogs/${dialogName}.html">
</compose>

Usage, you can give the name of any model-view/view pair as the first argument:

this.dialog.show('dialog-confirm',{
    headerText:'Warning!',
    messageText:'When you delete stuff - it is lost',
    confirmText:'Delete',
    cancelText:'I better not...'
}).then( function(result){
    console.log( 'The result is: '+result )
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM