admin管理员组文章数量:1403461
I'm testing AngularJs with Play Framework 2.0 (Scala). Play uses Closure to minimize Javascript files.
My file is as follows:
// Define a Module 'todoList' for Angular that will load the views. In this example the views are very simple, it's just to show
// the concept
angular.module('todoList', ['taskDoneFilter', 'todoServices']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/all', {templateUrl: 'assets/angular/all.html', controller: TodoCtrl}).
when('/task/:id', {templateUrl: 'assets/angular/task.html', controller: TaskDetailCtrl}).
otherwise({redirectTo: '/all'});
}]);
// This filter allows us to convert strings. In this case, it adds an extra tick besides a task indicating if it's done or no
angular.module('taskDoneFilter', []).filter('checkmark', function() {
return function(input) {
return input ? '\u2713' : '\u2718';
};
});
// When running tests with Jasmine the jsRoutes object is not defined, which means we need to use a default route for the http call below
// This kind of defeats the purpose of retrieving the routes via Play instead of hardcoding them, as we need a fallback for the tests
// but I decided to leave the code just to see that we have the possibility, in case I find a way to improve this.
var tasksUrl = '/tasks/all';
if(!(typeof jsRoutes === "undefined")) {
tasksUrl = jsRoutes.controllers.Application.tasks().url ;
}
// Definition of a Service, that stores all the REST requests independently from the controllers, facilitating change
angular.module('todoServices', ['ngResource']).
factory('All', function ($resource) {
return $resource(tasksUrl, {}, {
//The data model is loaded via a GET request to the app
query: {method: 'GET', params: {}, isArray: true}
});
})
.factory('Task', function ($resource) {
return $resource('tasks', {}, {
add: {method: 'POST'}
});
});
/**
* This is the controller behind the view, as declared by ng-controller
* All references to methods and data model in the view map to this controller
* @param $scope model data injected into the controller
* @constructor
*/
var TodoCtrl = ['$scope', 'All', 'Task', function($scope, All, Task) {
// We use the service to query for the data
$scope.todos = All.query();
//when submitting the form, this is called. Model in the form is referenced (todoText) and we add the task to
//the data model
$scope.addTodo = function() {
var txt = $scope.todoText;
$scope.todos.push({text: txt, done: false});
Task.save({msg: txt});
$scope.todoText = ''; //clear the input!
};
// calculates the remaining todos, automatically called when the model changes to update the view
// notice the use of 'angular' ponent for functional approach
$scope.remaining = function() {
var count = 0;
angular.forEach($scope.todos, function(todo) {
count += todo.done ? 0 : 1;
});
return count;
};
//another acton triggered by click (in this case on an anchor), which archives pleted tasks
$scope.archive = function() {
var oldTodos = $scope.todos;
$scope.todos = [];
angular.forEach(oldTodos, function(todo) {
if (!todo.done) $scope.todos.push(todo);
});
};
}];
// Task details controller, used in the routes to provide a second view for the application
var TaskDetailCtrl = ['$scope', '$routeParams', function($scope, $routeParams) {
$scope.id = $routeParams.id;
}];
But when minimizing, it bees:
var module$todo={};angular.module("todoList",["taskDoneFilter","todoServices"]).config(["$routeProvider",function($routeProvider){$routeProvider.when("/all",{templateUrl:"assets/angular/all.html",controller:TodoCtrl$$module$todo}).when("/task/:id",{templateUrl:"assets/angular/task.html",controller:TaskDetailCtrl$$module$todo}).otherwise({redirectTo:"/all"})}]);angular.module("taskDoneFilter",[]).filter("checkmark",function(){return function(input){return input?"\u2713":"\u2718"}});
var tasksUrl$$module$todo="/tasks/all";if(!(typeof jsRoutes==="undefined"))tasksUrl$$module$todo=jsRoutes.controllers.Application.tasks().url;angular.module("todoServices",["ngResource"]).factory("All",function($resource){return $resource(tasksUrl$$module$todo,{},{query:{method:"GET",params:{},isArray:true}})}).factory("Task",function($resource){return $resource("tasks",{},{add:{method:"POST"}})});
var TodoCtrl$$module$todo=["$scope","All","Task",function($scope,All,Task){$scope.todos=All.query();$scope.addTodo=function(){var txt=$scope.todoText;$scope.todos.push({text:txt,done:false});Task.save({msg:txt});$scope.todoText=""};$scope.remaining=function(){var count=0;angular.forEach($scope.todos,function(todo){count+=todo.done?0:1});return count};$scope.archive=function(){var oldTodos=$scope.todos;$scope.todos=[];angular.forEach(oldTodos,function(todo){if(!todo.done)$scope.todos.push(todo)})}}];
var TaskDetailCtrl$$module$todo=["$scope","$routeParams",function($scope,$routeParams){$scope.id=$routeParams.id}];
And then it stops working. Notice the:
var module$todo={};
and
var TodoCtrl$$module$todo=
which break the app.
Anyone knows why may this be happening?
I'm testing AngularJs with Play Framework 2.0 (Scala). Play uses Closure to minimize Javascript files.
My file is as follows:
// Define a Module 'todoList' for Angular that will load the views. In this example the views are very simple, it's just to show
// the concept
angular.module('todoList', ['taskDoneFilter', 'todoServices']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/all', {templateUrl: 'assets/angular/all.html', controller: TodoCtrl}).
when('/task/:id', {templateUrl: 'assets/angular/task.html', controller: TaskDetailCtrl}).
otherwise({redirectTo: '/all'});
}]);
// This filter allows us to convert strings. In this case, it adds an extra tick besides a task indicating if it's done or no
angular.module('taskDoneFilter', []).filter('checkmark', function() {
return function(input) {
return input ? '\u2713' : '\u2718';
};
});
// When running tests with Jasmine the jsRoutes object is not defined, which means we need to use a default route for the http call below
// This kind of defeats the purpose of retrieving the routes via Play instead of hardcoding them, as we need a fallback for the tests
// but I decided to leave the code just to see that we have the possibility, in case I find a way to improve this.
var tasksUrl = '/tasks/all';
if(!(typeof jsRoutes === "undefined")) {
tasksUrl = jsRoutes.controllers.Application.tasks().url ;
}
// Definition of a Service, that stores all the REST requests independently from the controllers, facilitating change
angular.module('todoServices', ['ngResource']).
factory('All', function ($resource) {
return $resource(tasksUrl, {}, {
//The data model is loaded via a GET request to the app
query: {method: 'GET', params: {}, isArray: true}
});
})
.factory('Task', function ($resource) {
return $resource('tasks', {}, {
add: {method: 'POST'}
});
});
/**
* This is the controller behind the view, as declared by ng-controller
* All references to methods and data model in the view map to this controller
* @param $scope model data injected into the controller
* @constructor
*/
var TodoCtrl = ['$scope', 'All', 'Task', function($scope, All, Task) {
// We use the service to query for the data
$scope.todos = All.query();
//when submitting the form, this is called. Model in the form is referenced (todoText) and we add the task to
//the data model
$scope.addTodo = function() {
var txt = $scope.todoText;
$scope.todos.push({text: txt, done: false});
Task.save({msg: txt});
$scope.todoText = ''; //clear the input!
};
// calculates the remaining todos, automatically called when the model changes to update the view
// notice the use of 'angular' ponent for functional approach
$scope.remaining = function() {
var count = 0;
angular.forEach($scope.todos, function(todo) {
count += todo.done ? 0 : 1;
});
return count;
};
//another acton triggered by click (in this case on an anchor), which archives pleted tasks
$scope.archive = function() {
var oldTodos = $scope.todos;
$scope.todos = [];
angular.forEach(oldTodos, function(todo) {
if (!todo.done) $scope.todos.push(todo);
});
};
}];
// Task details controller, used in the routes to provide a second view for the application
var TaskDetailCtrl = ['$scope', '$routeParams', function($scope, $routeParams) {
$scope.id = $routeParams.id;
}];
But when minimizing, it bees:
var module$todo={};angular.module("todoList",["taskDoneFilter","todoServices"]).config(["$routeProvider",function($routeProvider){$routeProvider.when("/all",{templateUrl:"assets/angular/all.html",controller:TodoCtrl$$module$todo}).when("/task/:id",{templateUrl:"assets/angular/task.html",controller:TaskDetailCtrl$$module$todo}).otherwise({redirectTo:"/all"})}]);angular.module("taskDoneFilter",[]).filter("checkmark",function(){return function(input){return input?"\u2713":"\u2718"}});
var tasksUrl$$module$todo="/tasks/all";if(!(typeof jsRoutes==="undefined"))tasksUrl$$module$todo=jsRoutes.controllers.Application.tasks().url;angular.module("todoServices",["ngResource"]).factory("All",function($resource){return $resource(tasksUrl$$module$todo,{},{query:{method:"GET",params:{},isArray:true}})}).factory("Task",function($resource){return $resource("tasks",{},{add:{method:"POST"}})});
var TodoCtrl$$module$todo=["$scope","All","Task",function($scope,All,Task){$scope.todos=All.query();$scope.addTodo=function(){var txt=$scope.todoText;$scope.todos.push({text:txt,done:false});Task.save({msg:txt});$scope.todoText=""};$scope.remaining=function(){var count=0;angular.forEach($scope.todos,function(todo){count+=todo.done?0:1});return count};$scope.archive=function(){var oldTodos=$scope.todos;$scope.todos=[];angular.forEach(oldTodos,function(todo){if(!todo.done)$scope.todos.push(todo)})}}];
var TaskDetailCtrl$$module$todo=["$scope","$routeParams",function($scope,$routeParams){$scope.id=$routeParams.id}];
And then it stops working. Notice the:
var module$todo={};
and
var TodoCtrl$$module$todo=
which break the app.
Anyone knows why may this be happening?
Share Improve this question edited Jan 6, 2013 at 17:08 Pere Villega asked Jan 6, 2013 at 17:00 Pere VillegaPere Villega 16.4k5 gold badges65 silver badges100 bronze badges2 Answers
Reset to default 10Your All
& Task
services are not 'minify safe'. You must use the array notation.
angular.module('todoServices', ['ngResource']).
factory('All', ['$resource', function ($resource) {
return $resource(tasksUrl, {}, {
//The data model is loaded via a GET request to the app
query: {method: 'GET', params: {}, isArray: true}
});
}])
.factory('Task', ['$resource', function ($resource) {
return $resource('tasks', {}, {
add: {method: 'POST'}
});
}]);
Also, define your controller with angular.module(...).controller()
:
angular.module(...).controller('TodoCtrl', ['$scope', 'All', 'Task', function($scope, All, Task) {
}]);
... and if you have a larger app, you can find where you aren't using named references by turning on strictDi (option to bootstrap call or ng-strict-di attribute in tag with ng-app attribute).
本文标签: javascriptWhy does Closure Compiler break this AngularJS scriptStack Overflow
版权声明:本文标题:javascript - Why does Closure Compiler break this AngularJS script? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744411559a2604976.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论