我们有以下指令:
.directive("directiveToggleElement", function(FlagsService) {
return {
restrict: "E",
scope: {},
link: function(scope, element, attrs)
{
scope.showMe = FlagsService.isOn(attrs.toggleKey);
scope.featureText = attrs.featureText;
var htmlTag = '<div class="panel ng-scope" ng-class="{selected: selected}" ng-click="selected = !selected;"></div>';
var htmlComment = '<!-- TogglePlaceholder: ' + attrs.toggleKey +'-->';
element.replaceWith(scope.showMe ? htmlComment + htmlTag : htmlComment);
// Listen for change broadcast from flagsservice to toggle local store
scope.$on('LocalStorage.ToggleChangeEvent.' + attrs.toggleKey, function(event, parameters) {
console.log('stuff changed - ' + parameters.key + ' ' + parameters.newValue);
scope.showMe = parameters.newValue;
element.replaceWith(scope.showMe ? htmlComment + htmlTag : htmlComment);
});
}
}
})
这个想法是,根据功能切换(或功能标志)的值,指令将输出带有标签的注释,或者仅输出注释。
初始元素 .replaceWith 按预期工作,但从 scope.$on 内部的调用会生成"类型错误:无法调用 null 的方法'replaceChild'"。我们在每次调用之前都检查了元素,无法发现明显的差异。
谁能解释为什么错误会被抛到这里,或者建议一种潜在的解决方法,使我们能够做同样的事情?
我们有一个工作指令来设置 ng-show 的值:
.directive("directiveToggle", function(FlagsService) {
return {
restrict: "A",
transclude: true,
scope: {},
link: function(scope, element, attrs)
{
scope.showMe = FlagsService.isOn(attrs.toggleKey);
// Listen for change broadcast from flagsservice to toggle local store
scope.$on('LocalStorage.ToggleChangeEvent.' + attrs.toggleKey, function(event, parameters) {
console.log('stuff changed - ' + parameters.key + ' ' + parameters.newValue);
scope.showMe = parameters.newValue;
});
},
template: '<div class="panel ng-scope" ng-show="showMe" ng-class="{selected: selected}" ng-click="selected = !selected;"><span ng-transclude></span></div>',
replace: true
}
})
但是我们更愿意从 DOM 中删除元素,而不是将显示设置为 none。
您仍然可以在自定义"指令切换"中使用 ng-if 指令,而无需控制器。要实现此目的,您需要使用 transclude 选项:
.directive("directiveToggle", function (FlagsService) {
return {
template: '<div ng-transclude ng-if="isEnabled"></div>',
transclude: true,
restrict: 'A',
scope: true,
link: function ($scope, $element, $attrs) {
var feature = $attrs.featureToggle;
$scope.isEnabled = FlagsService.isOn(feature);
$scope.$on('LocalStorage.ToggleChangeEvent.' + feature, function (event, parameters) {
$scope.isEnabled = parameters.newValue;
});
}
}
});
上面是从"指令切换"内部获取标记,然后将其包装在模板中,其中"ng-transclude"指令标记插入点。模板中还包括一个"ng-if"指令,该指令正在监视"directiveTemplate"的当前作用域上的"isEnabled"成员。
此方法的一个警告是,如果您有多个此指令实例,则需要指令来创建其自己的作用域/隔离作用域,否则"isEnabled"成员将在指令之间共享。