使用$ compile来处理自定义指令中的angular指令

时间:2015-11-20 12:25:37

标签: angularjs angularjs-directive

我正在创建一个指令,该指令将禁用应用它的元素内的所有元素。为简单起见,我们假设只禁用了按钮。在指令链接函数中,我只是为要禁用的元素设置disabled属性。这工作正常,但问题出现在某些按钮具有ng-disabled属性的情况下,在这种情况下,按钮会根据ng-disabled中的条件被禁用/启用,从而忽略指令逻辑

所以我考虑使用$compile并使用以下方法修复它:

当需要禁用按钮时,

1) Add disabled attribute to the buttons.
2) Check if buttons have 'ng-disabled' attribute. If so,keep its value in the same DOM element under a different attribute name.
3) Delete the ng-disabled attribute.
4) Recompile to reflect the change in attributes (So there will not be any ngDisabled checks on recompilation).

重新启用按钮时,

1) Remove disabled attributes
2) Check for attribute created in step (2) of above and add it to the ng-disabled attribute
3) Remove the backup attribute
4) Recompile

但这不起作用。即使属性不存在,仍然会评估ngDisabled条件。

指令代码:

function disableElements($compile) {
    return {
        restrict: "A",
        scope: {
            disableElements: "="
        },
        link: function (scope, elem, attr) {
            scope.$watch('disableElements', function (newVal) {
                var buttons;
                var ngDisabled;
                var backup;
                buttons = elem.find('button');
                if (newVal) {
                    buttons.attr('disabled', 'disabled');
                    for (var i = 0, j = buttons.length; i < j; i++) {
                        ngDisabled = $(buttons[i]).attr('ng-disabled');
                        if (typeof ngDisabled !== typeof undefined && ngDisabled !== false) {
                            $(buttons[i]).attr('backup', ngDisabled).removeAttr('ng-disabled');
                        }
                    }
                    $compile(elem.contents())(scope);
                } else {
                    buttons.removeAttr('disabled');
                    for (var i = 0, j = buttons.length; i < j; i++) {
                        backup = $(buttons[i]).attr('backup');
                        if (typeof backup !== typeof undefined && backup !== false) {
                            $(buttons[i]).attr('ng-disabled', backup).removeAttr('backup');
                        }
                    }
                    $compile(elem.contents())(scope);
                }

            });
        }
    };
}

示例视图和控制器

<input type="text" ng-model="vm.val">
<div disable-elements="vm.disableAll">
    <button type="button" ng-disabled="vm.val.length===0" ng-click="vm.buttonClicked()">With ng disabled</button>
    <button type="button" ng-click="vm.buttonClicked()">Without ng disabled</button>
</div>
<label><input type="checkbox" ng-model="vm.disableAll">Disable all</label>

function SampleController() {
    this.disableAll = true;
    this.val = '';
    this.buttonClicked = function () {
        alert("click");
    }

}

jsfiddle here

请让我知道此代码有什么问题,或者是否是解决此问题的正确方法。

1 个答案:

答案 0 :(得分:0)

重新编译内容并不会取消先前编译的指令。

实际上,没有简单的方法可以做你想做的事情。唯一正确的方法是停止使用ng-disable来使用你自己的自定义禁用指令,该指令会知道它的父指令“globalDisabled”状态。