Reputation: 55
Accessing scope in a link function within a directive is "undefined" following minification for a number of examples (using Closure Compiler) but works fine pre-minification.
For example, code below from the Angular tutorial with some alterations. After minification $scope.format is not picked up by the directive at any point. The directive shows the default format (Jul 15, 2015) without any errors. Prior to minification, the directive displays format as defined in $scope.format (7/15/2015 12:09:04 AM).
app.js
.controller('Controller', ['$scope', function ($scope) {
$scope.format = 'M/d/yy h:mm:ss a';
}])
.directive('myCurrentTime', bd.myCurrentTime.Directive.factory)
myCurrentTime-directive.js
'use strict';
goog.provide('bd.myCurrentTime.Directive.factory');
/**
* Example directive factory.
*
* @return {Object}
* @ngInject
* @export
*/
bd.myCurrentTime.Directive.factory = function ($interval, dateFilter) {
function link(scope, element, attrs) {
var format,
timeoutId;
function updateTime() {
element.text(dateFilter(new Date(), format));
}
scope.$watch(attrs.myCurrentTime, function (value) {
format = value;
updateTime();
});
element.on('$destroy', function () {
$interval.cancel(timeoutId);
});
// start the UI update process; save the timeoutId for canceling
timeoutId = $interval(function () {
updateTime(); // update DOM
}, 1000);
}
return {
link: link
};
};
// Added by ng-annotate
bd.myCurrentTime.Directive.factory.$inject = ["$interval", "dateFilter"];
html file:
<div ng-controller="Controller">
Date format: <input ng-model="format"> <hr />
Current time is: <span my-current-time="format"></span>
</div>
Upvotes: 2
Views: 732
Reputation: 1917
Are you using the Closure compiler's Advanced Compilation mode? Without seeing your minified code it's hard to pinpoint the problem, but here are some ideas:
In this part of your code:
.controller('Controller', ['$scope', function ($scope) {
$scope.format = 'M/d/yy h:mm:ss a';
}])
$scope.format
might be renamed to something like s.f
. Normally, this wouldn't be a problem, especially since $scope
is injected properly. However, you're referencing the format
property in the HTML, which the Closure compiler doesn't know about:
Date format: <input ng-model="format"> <hr />
Current time is: <span my-current-time="format"></span>
Try using $scope['format'] = 'M/d/yy h:mm:ss a'
instead - the Closure compiler never changes strings, so this should export the correct property name for the HTML. Now, remember - once you use a string to access a property, always use a string to access that property.
Similar to #1, attrs.myCurrentTime
might be renamed to something like a.m
. Try using a string property name (attrs['myCurrentTime']
) to ensure that the compiled JavaScript matches the HTML properly.
Again, these are just ideas at this point. If you post the minified code as a full example, we'll be able to help more.
Upvotes: 2