ng-show / ng-hide / ng-if 不适用于 Angular 指令

ng-show / ng-hide / ng-if don't work on Angular directive

本文关键字:Angular 指令 适用于 ng-if ng-hide ng-show 不适用      更新时间:2023-09-26

>我正在构建一个采用卡片形式的指令。当我加载卡片模板时,我想确保如果用户之前隐藏了卡片,则卡片是隐藏的。我可以通过 request.hide 属性跟踪这一点。

这是我的指令(准系统):

app.directive('request', ['$http', '$timeout', function($http, $timeout) {
    return {
        replace: true,
        templateUrl: '/assets/request.html',
        transclude: false,
        scope: {
            request: '='
        },
        controller: ['$scope', '$http', '$timeout', function($scope, $http, $timeout) {
            // Cool stuff goes in here
        }]
    };
}]);

这是我的模板:

<div>
    <div ng-hide"request.hide" class="card">
        <!-- Cool stuff goes in here -->
    </div>
</div>

页面加载时,每个request都有一个hide属性。从理论上讲,当我调用我的指令时,如果hide === true它应该被隐藏。不幸的是,情况似乎并非如此。无论我尝试什么,我都无法在初始化时隐藏我的指令。我尝试在根元素上使用 ng-hide="request.hide"ng-show="!request.hide"ng-if="!request.hide",但没有任何效果。

我想知道这些指令是否不适用于自定义指令的根元素,所以我尝试将我的指令包装在另一个div中,并在div 上使用 ng-hideng-showng-if .carddiv,现在是一个子元素,但这也没有效果。

似乎ng-hide要么根本没有被评估,要么在指令范围内定义request之前正在被评估。

您提供的模板标记中有一个小拼写错误,ng-hide 后缺少 = 符号。但我猜这只是你写问题时的错字。

否则,指令代码看起来不错,它应该可以工作。您应该仔细检查要将指令绑定到的"request"对象,并确保 hide 属性实际上是一个布尔值,而不是一个字符串。

ng-if、ng-show 和 ng-hide 都设置了观察程序,因此问题不应该是在填充范围之前计算表达式。

仅出于测试目的,请尝试在指令控制器中的范围内设置布尔值,然后进行隐藏或如果反对。

尝试在包装器上使用ngCloak - div .它应该隐藏div及其子项,只要角度仍在评估事物。

https://docs.angularjs.org/api/ng/directive/ngCloak

编辑:其实不然。 ngCloak不像我记忆中的那样工作。它隐藏了元素及其所有子元素,但前提是在编译阶段没有遇到它 - 这对我来说还为时过早。不过,您可以编写自己的隐身指令。

以下是ngCloak's来源:

var ngCloakDirective = ngDirective({
  compile: function(element, attr) {
    attr.$set('ngCloak', undefined);
    element.removeClass('ng-cloak');
  }
});

您需要在链接前/链接后阶段模仿其行为。

ng-show可能不可靠。

<div>
    <div ng-show"!!request.hide" class="card">
        <!-- Cool stuff goes in here -->
    </div>
</div>

我终于想出了解决问题的方法,尽管我仍然想知道导致问题的原因以及解决问题的最佳方法。

我有一个理论,即编译指令时没有评估ng-show/ng-hide/ng-if,所以我决定像以前一样在我的指令的根元素上使用ng-hide="hide",但是在我的控制器中,而不是立即设置$scope.hide = $scope.request.hide,我决定将其移动到延迟为 10 毫秒的$timeout块内, 这样:

$timeout(function() {
    $scope.hide = $scope.request.hide;
}, 10)

这会在编译指令后触发摘要循环,从而导致重新评估ng-hide。延迟足够长,以便指令编译,但又足够短,以至于用户无法察觉。