Пользовательская директива - незаконное использование директивы ngTransclude в шаблоне - PullRequest
0 голосов
/ 11 декабря 2018

Я использовал эту директиву для предотвращения двойных щелчков.

мой код:

export function cbOneClickOnly($parse, $compile): ng.IDirective {
    "use strict";
    return {
        compile: function(tElement: ng.IAugmentedJQuery, tAttrs: ng.IAttributes) {
            if (tAttrs.ngClick) {
                throw "Cannot have both ng-click and cb-one-click-only on an element";
            }
            tElement.attr("ng-click", "oneClick($event)");
            tElement.attr("ng-dblclick", "dblClickStopper($event)");
            tElement.removeAttr("cb-one-click-only");
            let theClickFunctionToRun = $parse(tAttrs["cbOneClickOnly"]);
            return {
                pre: function(scope: ng.IScope, iElement: ng.IAugmentedJQuery) {
                    let hasBeenClicked: boolean = false;
                    scope.oneClick = function(event: Event) {
                        if (hasBeenClicked) {
                            throw "Already clicked";
                        }
                        hasBeenClicked = true;
                        $(event.srcElement).attr("disabled", "disabled");
                        theClickFunctionToRun(scope, { $event: event });
                        return true;
                    };
                    scope.dblClickStopper = function(event: Event) {
                        event.preventDefault();
                        throw "Double click not allowed!";
                    };
                    $compile(iElement)(scope);
                }
            };
        },
        restrict: "A",
        scope: true
    };
}

, который затем добавляется в приложение следующим образом:

angular.module(moduleId, []).directive("cbOneClickOnly", ["$parse", "$compile", cbOneClickOnly])

и используется примерно так:

<md-button class="md-accent" cb-one-click-only="$ctrl.itemSaveClicked(item)">
     Save
</md-button>

Но я получаю эту ошибку:

> Error: [ngTransclude:orphan] Illegal use of ngTransclude directive in
> the template! No parent directive that requires a transclusion found.
> Element: <!-- ngIf: $ctrl.isSaveDisplayed() -->
> https://errors.angularjs.org/1.7.5/ngTransclude/orphan?p0=%3C!--%20ngIf%3A%20%24ctrl.isSaveDisplayed()%20--%3E
>     at eval (angular.js:138)
>     at Object.ngTranscludePostLink (angular.js:34687)
>     at eval (angular.js:1365)
>     at invokeLinkFn (angular.js:11235)
>     at nodeLinkFn (angular.js:10554)
>     at compositeLinkFn (angular.js:9801)
>     at publicLinkFn (angular.js:9666)
>     at lazyCompilation (angular.js:10080)
>     at boundTranscludeFn (angular.js:9844)
>     at controllersBoundTransclude (angular.js:10604) "<!-- ngIf: $ctrl.isSaveDisplayed() -->"

Это решение решает мою проблему, но надиректива с html, а моя - нет.

Я вручную удалил ng-transclude, например, так: iElement.removeAttr("ng-transclude");, и это привело к исчезновению текста внутри кнопки.

Какое решениедля этого стиля директивы, которая не имеет шаблона?

1 Ответ

0 голосов
/ 11 декабря 2018

Это была временная проблема, так как это решение говорит.

На самом деле простым решением было удалить атрибут ng-transclude, поскольку он явно не требовался в моей директиве атрибута.,

iElement.removeAttr("ng-transclude");
$compile(iElement)(scope);

Это затем удалило атрибут ng-transclude из родительского элемента, самой кнопки (не идеально - он удалил текст на кнопке).Который был проблемой синхронизации, потому что это бежало прежде, чем кнопка была загружена.

Чтобы запустить его после загрузки кнопки, я просто изменил pre на post внутри compile.

Например.

return { 
         pre: function(scope: ng.IScope, iElement: ng.IAugmentedJQuery) {
             let hasBeenClicked: boolean = false;...

становится

return { 
         post: function(scope: ng.IScope, iElement: ng.IAugmentedJQuery) {
             let hasBeenClicked: boolean = false;...

окончательное решение:

export function cbOneClickOnly($parse, $compile): ng.IDirective {
    "use strict";
    return {
        compile: function(tElement: ng.IAugmentedJQuery, tAttrs: ng.IAttributes) {
            delete tAttrs.ngTransclude;
            if (tAttrs.ngClick) {
                throw "Cannot have both ng-click and cb-one-click-only on an element";
            }
            tElement.attr("ng-click", "oneClick($event)");
            tElement.attr("ng-dblclick", "dblClickStopper($event)");
            tElement.removeAttr("cb-one-click-only");
            let theClickFunctionToRun = $parse(tAttrs["cbOneClickOnly"]);
            return {
                post: function(scope: ng.IScope, iElement: ng.IAugmentedJQuery) {
                    let hasBeenClicked: boolean = false;
                    scope.oneClick = function(event: Event) {
                        if (hasBeenClicked) {
                            throw "Already clicked";
                        }
                        hasBeenClicked = true;
                        $(event.srcElement).attr("disabled", "disabled");
                        theClickFunctionToRun(scope, { $event: event });
                        return true;
                    };
                    scope.dblClickStopper = function(event: Event) {
                        event.preventDefault();
                        throw "Double click not allowed!";
                    };
                    iElement.removeAttr("ng-transclude");
                    $compile(iElement)(scope);
                }
            };
        },
        restrict: "A",
        scope: true
    };
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...