4

我正在用Play Framework 2.0(Scala)测试AngularJs。 Play使用Closure来最小化Javascript文件。为什么Closure Compiler会破坏这个AngularJS脚本?

我的文件如下:

// 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' component 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 completed 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; 
}]; 

但减少的时候,就变成:

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}]; 

然后它停止工作。注意:

var module$todo={}; 

var TodoCtrl$$module$todo= 

它打破了应用程序。

任何人都知道为什么会发生这种情况?

回答

10

All & Task服务不是 '运行如下安全'。您必须使用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'} 
     }); 
    }]); 

而且,与angular.module(...).controller()定义控制器:

angular.module(...).controller('TodoCtrl', ['$scope', 'All', 'Task', function($scope, All, Task) { 
}]); 
+4

恕我直言,只允许依赖注入机制应该是数组表示法。 –

+0

为延迟接受答复道歉,我不得不验证,直到今天不能这样做! –

0

...如果你有一个更大的应用程序,你可以找到打开strictDi在您不使用命名引用(选项在具有ng-app属性的标签中引导调用或ng-strict-di属性)。

相关问题