once-show should hide undefined elements
NinjaCross opened this issue · 0 comments
NinjaCross commented
I think that once-show should hide undefined elements before adding a watch for them.
This will satisfy the case when a data member is purposely omitted from the data model for optimization purposes.
This small changes in code did the trick for me:
function setOneTimeBinding($scope, element, watch, watcherParser, bindingParser, done,definitioName) {
// get value to watch
var watchingValue = watcherParser($scope);
// if we have a valid value, render the binding's value
if (watchingValue !== undefined) {
// if watching and binding $parsers are the same, use watching's value, else $parse the new value
return done(element, watcherParser == bindingParser ? watchingValue : bindingParser($scope));
}
if (definitioName == 'onceShow')
{
$(element[0]).hide();
}
// we do not have a valid value, so we register a $watch
var watcherRemover = $scope.$watch(watch, function (newValue) {
// wait until we have a valid value
if (newValue == undefined) return;
// remove this $watch
removeWatcher();
// if watching and binding $parsers are the same, use watching's value, else $parse the new value
return done(element, watcherParser == bindingParser ? newValue : bindingParser($scope));
});
function removeWatcher() {
if (watcherRemover) {
watcherRemover();
}
}
$scope.$on("$destroy", removeWatcher);
}
var once = angular.module('once', []);
function makeBindingDirective(definition) {
once.directive(definition.name, ['$parse', function ($parse) {
return {
priority: definition.priority || 0,
link: function ($scope, element, attrs) {
var watch = attrs.onceWaitFor || attrs[definition.name];
var watcherParser = $parse(watch);
var bindingParser = attrs.onceWaitFor ? $parse(attrs[definition.name]) : watcherParser;
setOneTimeBinding($scope, element, watch, watcherParser, bindingParser, definition.binding, definition.name);
}
};
}]);
}