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

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

我正在构建一个采用卡片形式的指令。当我加载卡片模板时,如果用户之前隐藏了卡片,我想确保卡片被隐藏。我可以通过 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 中并使用 ng-hideng-show,或 .card div 上的 ng-if,它现在是一个子元素,但也没有任何效果。

好像 ng-hide 根本没有被评估,或者在指令范围内定义 request 之前被评估。

尝试在 wrapper-div 上使用 ngCloak。只要 angular 仍在评估事物,它就应该隐藏 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');
  }
});

您需要在 pre-/post-link 阶段模仿它的行为。

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

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

ng-if、ng-show 和 ng-hide 都设置了观察者,因此问题不应该是在填充范围之前对表达式进行求值。

仅出于测试目的,请尝试在指令控制器中的作用域上设置一个布尔值,然后执行 hide or if against。

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"根元素和以前一样,但在我的控制器中,我决定将其移动到 $timeout 块中,延迟 10 毫秒,而不是立即设置 $scope.hide = $scope.request.hide,如下所示:

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

这会在编译指令后触发一个摘要循环,导致 ng-hide 被重新计算。延迟足够长以供指令编译,但也足够短以致于用户察觉不到。