如何将pagedown指令设置为$ dirty?

8 angularjs angularjs-directive

我有以下pagedown指令.每当我更改/编辑textarea时,如何将我的指令设置为脏?

app.directive('pagedown', ['$compile', '$timeout', function ($compile, $timeout) {
var nextId = 0;
var converter = Markdown.getSanitizingConverter();

converter.hooks.chain("preBlockGamut", function (text, rbg) {
    return text.replace(/^ {0,3}""" *\n((?:.*?\n)+?) {0,3}""" *$/gm, function (whole, inner) {
        return "<blockquote>" + rbg(inner) + "</blockquote>\n";
    });
});

return {
    restrict: "E",
    scope: {
        content: "=",
        modal: '=modal'
    },
    link: function (scope, iElement, attrs) {

        var editorUniqueId;

        if (attrs.id == null) {
            editorUniqueId = nextId++;
        } else {
            editorUniqueId = attrs.id;
        }

        var newElement = $compile(
            '<div>' +
                '<div class="wmd-panel">' +
                    '<div data-ng-hide="modal.wmdPreview == true" id="wmd-button-bar-' + editorUniqueId + '"></div>' +
                    '<div>' +
                        '<textarea data-ng-hide="modal.wmdPreview == true" class="wmd-input" id="wmd-input-' + editorUniqueId + '" ng-model="content" >' +
                        '</textarea>' +
                    '</div>' +
                    '</div>' +
            '</div>')(scope)
        ;

        iElement.append(newElement);

        var help = angular.isFunction(scope.help) ? scope.help : function () {
            alert("Do you need help?");
        };

        var editor = new Markdown.Editor(converter, "-" + editorUniqueId, {
            handler: help
        });

        var editorElement = angular.element(document.getElementById("wmd-input-" + editorUniqueId));

        editor.hooks.chain("onPreviewRefresh", function () {
            // wire up changes caused by user interaction with the pagedown controls
            // and do within $apply
            $timeout(function () {
                scope.content = editorElement.val();
            });
        });

        editor.run();
    }
}
}]);
Run Code Online (Sandbox Code Playgroud)

在HTML中:

<pagedown class="pagedown-admin"
          modal="ahs.modal"
          content="ahs.modal.data.text"></pagedown>
Run Code Online (Sandbox Code Playgroud)

现在只有textarea被设置为$ dirty而不是整个pagedown指令.有人可以指点我,我做错了什么?

小智 3

如果没有手动黑客攻击或正确的元素类型,指令不可能是。$dirty

一个inputtextareaform可以成为$dirty并将接收该类(所以是的,元素是其中之一的指令 - 完整的指令可以是 $ dirty ng-dirty,如果这就是人们想要推理的方式)。

你能做的就是指令元素替换form为元素,并且对所述表单中的输入控件的任何操作都会在表单上设置适当的 $dirty flah / dirty 类。

就像这样:

.directive('', function () {
  return {
    replace: true, 
    template: '<form name="myForm"></form>'
  }
});
Run Code Online (Sandbox Code Playgroud)

但是,替换已被弃用 (目前您仍然可以使用它)。


newElement相反,我建议您用aform而不是 a包装 的内容,并接受整个指令模板不会被标记为 的div事实。$dirty

var newElement = $compile(
    '<form name="myForm">' +
        '<div class="wmd-panel">' +
            '<div data-ng-hide="modal.wmdPreview == true" id="wmd-button-bar-' + editorUniqueId + '"></div>' +
            '<div>' +
                '<textarea data-ng-hide="modal.wmdPreview == true" class="wmd-input" id="wmd-input-' + editorUniqueId + '" ng-model="content" >' +
                '</textarea>' +
            '</div>' +
            '</div>' +
    '</form>')(scope)
;
Run Code Online (Sandbox Code Playgroud)

请问这一切的目的是什么?


如果你真的想将指令设置为$dirty(唉,我不明白为什么) - 你可以这样做(考虑到上述更改):

 scope.$watch('myForm.$dirty', function (v) {
   attrs.$set('dirty', !!v);
 });
Run Code Online (Sandbox Code Playgroud)

您不能将其设置$dirty为包含指令元素的属性,如$dirty它不是有效的属性名称。我相信这就是您所能得到的最接近的结果。


编辑

根据下面的评论,我唯一的结论是你一定忘记了名字的表单(或 ngForm)。

如果没有设置名称属性,您将无法访问$dirty范围内的表单标志。如果您在检查器中查看,则会设置类,但仅当您在您的表单上公开表单对象时,这些标志才可用。$scope(通过命名完成)时,这些标志才可用。

请尝试以下操作:

<form name="myForm">
  <pagedown-directive></pagedown-directive>
  <button ng-disabled="!myForm.$dirty"></button>
</form>
Run Code Online (Sandbox Code Playgroud)

myForm.$dirty只有在是 的情况下才应该启用该按钮true。隔离范围不会损坏表单内事物的流动,所以你应该在那里被覆盖。

这是一个JSBin,展示了它的工作原理。