1

我有以下指令:

.directive('confirmOnExit', function () {
    return {link: function ($scope, elem, attrs) {
            window.onbeforeunload = function () {
                if ($scope.contextForm.$dirty) {
                    return "Unsaved data detected.";
                }
            }
        }
    };
})

如您所见,该指令写得并不好,因为它直接引用了表单contextForm

我想做的是更通用的东西(所以我也可以在其他形式上使用它):

.directive('confirmOnExit', function ($window) {
    return {link: function ($scope, elem, attrs) {
            // Make sure code is only executed if directive is place on a form
            // Should I even do this here??
            if (elem[0].tagName == "FORM") {
                var form = elem[0];
                $window.onbeforeunload = function () {
                if (form.className.indexOf("ng-dirty") > -1) {
                    return "Unsaved data detected.";
                }
            }
        }
    };
})

你会注意到代码仍然很丑,因为form.hasClass("ng-dirty")或者form.$dirty()没有工作......我也认为访问elem[0]是不正确的......

我真的很感激一些帮助!

谢谢!!

4

2 回答 2

2

您应该依赖 FormController ( http://docs.angularjs.org/api/ng.directive:form.FormController )

所以你可以做什么:

  1. 添加 "require: '^ngForm'"以请求表单控制器作为链接功能的参数
  2. 向链接函数添加另一个参数(类型formCtrl
  3. 利用formCtrl.$dirty

如果您不清楚,请使用指令创建 plunker 示例,我将尝试对其进行这些更改。

于 2013-06-07T10:24:37.457 回答
2

来自AngularJS 表单文档

如果指定了 name 属性,则表单控制器以该名称发布到当前范围。

$eval因此,您可以通过使用name属性访问该控制器:

.directive('confirmOnExit', function () {
    return {
        link: function ($scope, elem, attrs) {
            var formCtrl = $scope.$eval(attrs.name);
            window.onbeforeunload = function () {
                if (formCtrl.$dirty) {
                    return "Unsaved data detected.";
                }
            }
        }
    };
});
于 2013-06-07T10:59:22.190 回答