实施模态工厂?

时间:2016-09-25 17:11:37

标签: javascript jquery html css

我一直在使用模式作为一种手段,通过几个不同的前端框架与我的应用中的用户进行一段时间的通信。逻辑通常是相同的,定义模态的html,然后通过一些点击事件呈现它。

随着我的应用程序的增长,我用于用户提示或确认的模态数量也会增加 - 这些模式可以包含从文本输入到表单到下拉列表等所有内容。

我目前的方法是在一个单独的html文件中写出每个单独的模态,并简单地通过他们的ID调用它们但我觉得这是低效的,因为有大量重复的样板代码,所以我想知道最好的方法将动态创建模态同时保持代码尽可能轻和干净?

我一直在想像一个"莫代尔工厂"在哪里传递模态的内容以及高度,宽度,样式等,这是一个很好的方法吗?

感谢您的任何意见!

1 个答案:

答案 0 :(得分:1)

我对从服务器加载的Forms/HTML Content所做的是在页面末尾创建一个ID为PartialViewDialog的div - (我在对话框中加载部分视图)

这是基于Bootstrap 3. * - (基于Frontend框架的HTML结构

所以HTML就像这样:

<body>

<!-- Other page content -->


<div class="modal fade" id="PartialViewDialog">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title" data-modal="title"></h4>
            </div>
            <div class="modal-body" data-modal="content">

            </div>
            <div class="modal-footer" data-modal="footer">
            </div>
        </div>
    </div>
</div>

</body>

然后在JS中,我创建了一个对话框管理器:

   var MyApp = MyApp || {};

MyApp.UIHelper = MyApp.UIHelper || {};

MyApp.UIHelper.DialogManager = (function () {

    "use strict";


    var self = {};
    self.divId = null;
    self.dialog = null;
    self.dialogBody = null;
    self.dialogTitle = null;
    self.dialogFooter = null;
    self.actionUrl = "";
    self.modalObject = null;
    self.options = {};

    function Initilize(divId, options) {

        self.options = $.extend({ buttons: [] }, options);
        self.divId = divId;
        self.dialog = $(self.divId);
        self.dialogBody = self.dialog.find('*[data-modal="content"]');
        self.dialogTitle = self.dialog.find('*[data-modal="title"]');
        self.dialogFooter = self.dialog.find('*[data-modal="footer"]');
        self.BootgridObject = null;
    };

    function OpenPartialViewDialog(url, title, preprocessingFunction, postProcessingFunction) {

        // Create the buttons
        var options = self.GetPartialViewButtons(url, preprocessingFunction, postProcessingFunction);

        // Initialise the PartialViewDialog with Buttons
        Initilize('#PartialViewDialog', options);

        // Set the URL for Ajax content load and Form Post
        self.actionUrl = url;

        // Set Dialog Title
        self.dialogTitle.html(title);

        // Open the PartialViewDialog
        self.OpenModel();
    };


    // This Method creates the buttons for the Form dialog
    // e.g Save, Cancel, Ok buttons
    self.GetPartialViewButtons = function (url, preprocessingFunction, postProcessingFunction) {

        // I only need Save and Cancel buttons always so I create them here
        var buttons = {
            buttons: {
        // I create a save button which Posts back the Form in the Dialog
                Save: {
                    Text: "Save",
                    css: "btn btn-success",
                    click: function () {

                        // Call a function before sending the Ajax request to submit form
                        if (preprocessingFunction) { preprocessingFunction(); }

                        $.ajax({
                            type: "POST",
                            url: url,
                            // This Dialog has a Form - which is Post back to server
                            data: self.dialogBody.find("form").serialize(),
                            success: function (response) {
                                // TODO: Check if response is success - 
                                // Apply your own logic here
                                if (response.hasOwnProperty("IsSuccess")) {

                                    if (response.IsSuccess) {
                                        self.dialogBody.html("");
                                        self.dialog.modal("hide");
                                        // TODO: Show Success Message
                                        // You can call another function if you want
                                        if (postProcessingFunction) {
                                            postProcessingFunction();
                                        }
                                    } else {
                                        // If failure show Error Message    
                                    }
                                } 
                            },
                            error: function (response) {
                               // If failure show Error Message 
                            }
                        });
                    }
                },
                Cancel: {
                    Text: "Cancel",
                    css: "btn btn-danger",
                    click: function () {
                        self.dialogBody.html("");
                        self.dialogFooter.html("");
                        self.dialogTitle.html("");
                        self.dialog.modal("hide");
                    }
                }
            }
        };
        return buttons;
    };


    // dynamic creating the button objects
    self.CreateButtonsHtml = function () {
        var htmlButtons = [];
        $.each(self.options.buttons, function (name, props) {
            var tempBtn = $("<button/>", {
                text: props.Text,
                id: "btn_" + props.Text,
                "class": props.css + "",
                click: props.click
            }).attr({ "style": "margin-right: 5px;" });

            htmlButtons.push(tempBtn);

        });
        return htmlButtons;
    };


    // This method will load the content/form from server and assign the modal body - it will assign the buttons to the Modal Footer and Open the Dialog for user
    self.OpenModel = function () {
        $.ajax({
            url: self.actionUrl,
            type: "GET",
            success: function (response) {          
                // Handle response from server - 
                // I send JSON object if there is Error in loading the content - otherwise the result is HTML           
                if (response.hasOwnProperty("HasErrors")) { 
                    // Means some error has occured loading the content - you will have to apply your own logic
                } else {

                    //Server return HTML - assign to the modal body HTML        
                    self.dialogBody.html(response);
                    self.modalObject = self.dialog.modal();
                    // show modal
                    self.modalObject.show();
                }
            }
        });

        // Create the buttons in the Dialog footer
        var buttons = self.CreateButtonsHtml();
        self.dialogFooter.html('');
        for (var i = 0; i < buttons.length; i++) {
            self.dialogFooter.append(buttons[i]);
        }
    };
    return {
        OpenPartialViewDialog: OpenPartialViewDialog,
    };

})();

然后每当我需要从服务器打开一个对话框时,我可以这样称呼它:

MyApp.UIHelper.DialogManager
          .OpenPartialViewDialog('/Content/Load', "My Title", 
                          function(){alert('pre-process')}, 
                          function(){alert('post-process')}
                  );

注意:单击“保存”按钮时会调用PreProcess + PostProcess

这是一个工作/演示示例,它显示了上述JS的功能 - 希望它有所帮助 在演示中,我从div id="dummycontent"

加载虚拟HTML

小提琴:https://jsfiddle.net/1L0eLazf/

按钮小提琴:https://jsfiddle.net/1L0eLazf/1/