jquery-ui - AngularJS 嵌套模式对话框

标签 jquery-ui angularjs modal-dialog angular-ui

我正在将使用类似 Oracle 表单的技术创建的大型 CRUD 业务应用程序移植到 Web(HTML5/AngularJS/RESTful-web-services)。

业务逻辑设置的部分方式取决于模式对话框的可用性,显示 CRUD 网格。首先,用户...

  • 点击网格中的一行
  • 在行的第一个字段中输入数据
  • 按 Enter
  • 光标被发送到右侧的下一个字段
  • 等等
  • 他们编辑其他字段,等等
  • 他们点击页面上某处的“保存”
  • 进行验证,调用网络服务 -> 数据已存储。

我已经通过 AngularUI 的 ng-grid 构建了该部分。

下一步是我绊倒的地方:

  • 双击网格行,会出现一个新的 MODAL 对话框,显示“详细网格”。
  • 您可以编辑/删除网格中的任何内容,也可以再次双击网格行,然后会出现另一个新的模态对话框,显示“详细信息网格”。等等。

当我通过 Angular UI 的 $dialog 服务尝试此操作时,我很快就遇到了障碍 - 嵌套 $dialog 的 (e.g. see this issue on the GitHub repos) 有很多问题。 ,更令人担忧的是,他们最近(2 个月前)决定简单地放弃旧的对话框,因为它有太多问题,and rewrite it from scratch .

我向其他 Angular 开发人员提出的问题是,你们如何处理嵌套模式对话框?您是否使用其他库 - 例如jQueryUI 的对话框?如果是这样,你如何“以 Angular 方式”使用它们?即不在 Controller 中混合 DOM 处理?我尝试follow the example of another SO question它确实有效,但它将对话框的 HTML 嵌入到页面的部分中 - 这不好(例如,想象一下必须在所有 Angular 中嵌入通过 F1 显示的帮助对话框的所有 HTML 代码(“显示键盘快捷键对话框”) HTML 模板部分!

我正在考虑通过 $http 加载对话框模板(就像 Angular UI 对话框一样)并通过 ngIninclude 注入(inject)内容,但这意味着我必须在 DOM 中为它们保留一个占位符('#dialogPlace' 或其他东西) ) - 由于我要处理的嵌套“深度”可能是无限的,恐怕我将不得不自己编写“堆栈处理”代码,一路添加 DOM 元素。天知道这本身会导致什么......

我真的很喜欢 Angular,但我的问题域需要一个用于嵌套模式对话框的可靠工作组件。我希望有人遇到过这个问题,并有一个干净的、类似 Angular 的解决方案......

最佳答案

由于无法通过“重建中”的 AngularUI 对话框服务来解决这个问题,所以我使用了 jQueryUI 的对话框(它没有模态生成模态生成模态的问题...),并创建了一种“迷你-我自己的框架”。我所做的很多工作都是基于 AngularUI 对话框的源代码,而且它似乎工作得很好。

这是我编码的 Angular 服务( typescript 代码,因此它有一些类型规范 - 但除此之外是纯 Javascript)。由于它将生成模式对话框,因此我将该服务称为“Plato”:-)

...

export function addNewServices(application:ng.IModule) {
    application.factory('Plato', ['$http', '$compile', function($http, $compile) {
        return {
            showDialog: function(scope, strTile:string, templateUrl:string, dialogOptions, callback) {
                scope.dialogOptions = dialogOptions;
                scope.dialogOptions.callback = callback;
                $http.get(
                    templateUrl,
                    {timeout:globals.timeoutInMs, cache:false}
                ).success(function(response, status, header, config) {
                    var newDialogId = Sprintf.sprintf("npInnerDlg%d", globals.dialogCounter);
                    globals.dialogCounter += 1;
                    var modalEl = angular.element('<div id="' + newDialogId + '">');
                    modalEl.html(response);
                    $('body').append(modalEl);
                    $compile(modalEl)(scope);
                    var component = $('#' + newDialogId);
                    scope.dialogOptions.jquiDialog = component;
                    component.dialog({
                        autoOpen:false,
                        modal:true,
                        title:strTile
                    });
                    component.dialog("open");
                }).error(function(data, status, header, config) {
                    document.body.style.cursor  = 'default';
                    if (status == 406) {
                        console.log("Received 406 for:" + header + " # " + config);
                        alert("Received 406 from web service...");
                    } else {
                        console.log("Status:" + status);
                        console.dir(config);
                        alert("Timed-out waiting for data from server...");
                    }
                });

            }
        };
    }]);
}

...并像这样使用它:

首先,要显示对话框的调用代码:

var dialogOptions = {
    callback: function() {
        if (dialogOptions.result !== undefined) {
            cust.mncId = dialogOptions.result.whateverYouWant;
        }
    },
    result: {}
};

Plato.showDialog(
    $scope,
    'Choose something...',
    '/static/partials/municipalityLOV.html',
    dialogOptions
}

像往常一样使用 Angular Controller 和指令的 HTML 部分模板:

<div data-ng-controller="controllerMunicipalitiesLOV">
    <div data-ng-grid="..."
    ...

模态对话框 Controller 具有如下处理程序:

var dialogOptions = $scope.$parent.dialogOptions;
$scope.close = function(result) {
    dialogOptions.result.whatever = ....;
    dialogOptions.jquiDialog.dialog("close");
    dialogOptions.callback();
}; 

我基本上传递给showDialog:

  • 调用者的范围,我在其中存储传递的“dialogOptions”
  • 对话框标题
  • 对话框的 HTML 模板
  • “dialogOptions”,其中的内容在 .result 中的对话框中传递和传递
  • “dialogOptions”还包含回调

这个设计是一个完整的黑客,温和地说,但它有效:我使用调用者的范围来存储dialogOptions,并且在对话框的 Controller 内,我使用$scope.$parent.dialogOptions,来读取传入的内容调用者,并存储回调将读取的任何结果(“dialogOptions”充当两个范围之间的桥梁)。

至少截至 2013 年 7 月,这是我发现/破解的唯一 Angular-y 方式来创建可以以嵌套方式生成的模式对话框(例如,controllerMunicipalitiesLOV Controller 依次调用 showDialog,另一个 Controller 调用再次,等等)。

我希望我知道一种将“dialogOptions”作为附加参数传递给模式对话框 Controller 的方法 - 不幸的是我不太熟悉 Angular 内部;非常欢迎任何帮助(这将使这个界面更加清晰)。

希望这对某人有帮助。

关于jquery-ui - AngularJS 嵌套模式对话框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18078233/

相关文章:

jquery - 跨多个字段记住 jQuery UI 日期选择器中最后选择的月份

javascript - 使用 Javascript 测量点击次数?

javascript - 如何为单个实例动态更改 buttonImage?

jQuery UI 和 jQuery.each()

javascript - 跟踪网站上所有访问者的光标移动

html - 如何使用 laravel ajax 将另一个文件中的模态显示到我的 html 中

javascript - 如何使用 JavaScript 防止窗口关闭而不弹出带有 "Are You Sure You Want To Leave This Page"消息的弹出窗口?

javascript - Angular 范围变量和插件范围

jquery - Google Places Photos API 以什么格式返回图像?

html - 如何处理下拉angular-ui中的大元素列表?