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-hide
、ng-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
被重新计算。延迟足够长以供指令编译,但也足够短以致于用户察觉不到。
我正在构建一个采用卡片形式的指令。当我加载卡片模板时,如果用户之前隐藏了卡片,我想确保卡片被隐藏。我可以通过 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-hide
、ng-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
被重新计算。延迟足够长以供指令编译,但也足够短以致于用户察觉不到。