Can someone please shed light on why simple optimizations are failing for me in AngularJS? More importantly, how can I get them to work? (best practice/clarification for defining controllers is welcome too).
Here's my scenario, greatly simplified.
I'm using this HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html ng-app="">
<head>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/excite-bike/jquery-ui.css" type="text/css" rel="stylesheet" />
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min.js" type="text/javascript"></script>
<script src="simple_script.js" type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js" type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js" type="text/javascript"></script>
<script>
//inline JS here
$(function() {
var spinner = $( "#qtySpinner" ).spinner({
spin: function( event, ui ) {
scope.qty = ui.value;
scope.$digest();
//console.log( event );
}
}); //end spinner
var scope = angular.element(spinner).scope();
});
</script>
<title>Angular Testing</title>
</head>
<body>
<div ng-controller="InvoiceCntl">
<b>Invoice:</b><br>
<br>
<table>
<tr>
<td>
Quantity
</td>
<td>
Cost
</td>
</tr>
<tr>
<td>
<input id="qtySpinner" type="integer" min="0" ng-model="qty" required="">
</td>
<td>
<input type="number" ng-model="cost" required="">
</td>
</tr>
</table>
<hr>
<b>Total:</b> {{calculate(qty,cost)}}
</div>
<br>
</body>
</html>
And I'm using this highly minification proof (I thought) JS file as "simple_script.js", which actually works as is:
//this works
window["InvoiceCntl"] = function ($scope) {
$scope["qty"] = 1;
$scope["cost"] = 19.95;
$scope["calculate"] = function (xval, yval) {
return xval * yval;
};
}
Minified using Google Closure Compiler (http://closure-compiler.appspot.com/home) with SIMPLE_OPTIMIZATIONS, I get this, which breaks:
//this breaks, seemingly because "a" replaces "$scope"?
window.InvoiceCntl=function(a){a.qty=1;a.cost=19.95;a.calculate=function(a,b){return a*b}};
I presume it's because $scope is a key word Angular looks for (Dependency Injection?), because when I add the extra step, manually, of passing $scope and assigning it to a in the first line of the function, it works. Like so:
//manually passing "$scope" and immediately assigning it to "a" works
window.InvoiceCntl=function($scope){var a=$scope;a.qty=1;a.cost=19.95;a.calculate=function(a,b){return a*b}};
$scope behave like a normal function parameter in this situation?$scope configurable or is it a fixed key word, i.e., could I changed the key word to "$myscope" when I'm defining the controller? (not sure that helps me anyway)Thanks.
You should read http://docs.angularjs.org/tutorial/step_05
I think your concern about injecting '$scope' is correct. You can inject like following.
var module = angular.module('youApp', []);
module.controller('yourCtrl', ['$scope', function($scope) {
$scope["something"] = "somevalue";
})];
Edit: The minification renames $scope, you can prevent this by adding:
InvoiceCntl.$inject = ['$scope'];