NgIf times with angular
I am using tabs in an Angular application using ngIf to lazy load directives and controls within them when users need it. The problem is that I don't want to recreate the tab if users navigate through it, and for that purpose I use this trick to initialize the tab only once and show it when the users are needed then:
<button ng-click="tab.show=!tab.show">Toggle tab</div>
<div ng-if="tab.show || tab.initialized" ng-show="tab.show" ng-init="tab.initialized=true">
tab content
</div>
What I want to achieve is to implement this behavior with a custom directive, such ng-if-once="tab.show"
as reusing the core ngIf and ngShow directives if possible. Any ideas?
EDIT
This is my workaround, but ngIf keeps working after the correct value is set:
app.directive('ngIfOnce', ['ngIfDirective', 'ngShowDirective', function (ngIfDirective, ngShowDirective) {
var ngIf = ngIfDirective[0];
var ngShow = ngShowDirective[0];
return {
transclude: ngIf.transclude,
priority: ngIf.priority,
terminal: ngIf.terminal,
restrict: ngIf.restrict,
link: function ($scope, $element, $attr) {
$attr.ngIf = $attr.ngShow = $attr['ngIfOnce'];
var unregisterWatcher = $scope.$watch($attr.ngIf, function (newVal) {
if (newVal) {
$attr.ngIf = true;
unregisterWatcher();
}
});
ngIf.link.apply(ngIf, arguments);
ngShow.link.apply(ngShow, arguments);
}
};
}]);
source to share
This might be a possible solution:
myApp.directive("ngIfOnce", function () {
return {
restrict: 'A',
transclude: true,
template: "<span ng-show='originalNgIf' ng-if='initialized' ng-transclude></span>",
scope:{
ngIfOnce: '='
},
link: function (scope, attr) {
console.log( scope.ngIfOnce );
scope.$watch('ngIfOnce', function (newVal, oldVal) {
console.log("changed" + newVal);
scope.originalNgIf = newVal;
if (scope.initialized === undefined && scope.originalNgIf === true) scope.initialized = true;
});
}
}
});
It translates the content of ngIfOnce and executes ngIf only once, while ngShow is executed every time the variable passed as an attribute changes
source to share