AngularJS ломается при минимизации при использовании службы

Хорошо, я новичок в AngularJS, поэтому, пожалуйста, не смейтесь, если это легко. Я пытаюсь следовать руководству по стилю AngularJS для Teams от Тодда Мотто. Я знаю, что это не очень похоже, так как я пытался сократить код. Я использую Grunt, чтобы испортить свой код. Если я отключу коверканье, оно сработает. В противном случае я получаю сообщение об ошибке:

Error: [$injector:unpr] Unknown provider: aProvider <- a

Я знаю, что это из-за того, что имя искажается, поэтому он не знает, на что его сопоставить, но я понятия не имею, как/куда ввести правильное имя. Я пытался отследить это. Я думаю, что это происходит, когда мы пытаемся разрешить маршрут, а DataService вводится, и, поскольку для нашего DataService нет вставки, я думаю, что он искажается.

Я пытался максимально сократить свой код. Это также зависит от angular и angular-route, а также от файла с именем data.json (это может быть что угодно, это не имеет большого значения). Затем просто запустите grunt debug.

Пожалуйста, дайте мне знать, если я что-то пропустил, и спасибо за ваше время.

Структура файла

├── data.json
├── gruntfile.js
├── index.html
└── js
    ├── app
    │   └── app.js
    └── vendor
        ├── angular-route.js
        └── angular.js

gruntfile.js

module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        uglify: {
            debugMine: {
                options: {
                    wrap: true,
                    sourceMap: true,
                    mangle: false,
                },
                files: { 'js/production.min.js': [
                    'js/app/app.js',
                ]}
            },
            debugVendor: {
                files: { 'js/vendor.min.js': [
                    'js/vendor/angular.js',
                    'js/vendor/angular-route.js',
                ]}
            }
        },
        connect: {
            server: {
                options: {
                    port: 8000,
                }
            }
        },
        watch: {
            myscripts: {
                files: ['js/app/**'],
                tasks: ['uglify:debugMine'],
            },
            options: {
                livereload: true,
                spawn: false
            },
            vendorscripts: {
                files: ['js/vendor/**'],
                tasks: ['uglify:debugVendor'],
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-connect');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-watch');

    grunt.registerTask('debug',
                        'Create a debug build of the code',
                        [
                            'uglify:debugMine',
                            'uglify:debugVendor',
                            'connect:server',
                            'watch',
                        ]);
};

index.html

<!DOCTYPE html>
<html ng-app="app">
    <head>
        <meta charset="utf-8">
        <title>Mangled Names Test</title>
    </head>
    <body>

        <h2>I'm above the content</h2>
        <hr>
        <!-- Begin Content -->
        <div ng-view></div>
        <!-- End Content -->
        <hr>
        <h2>I'm below the content</h2>

        <!-- Begin Release Scripts -->
        <script src='js/vendor.min.js'></script>
        <script src='js/production.min.js'></script>
        <!-- End Release Scripts -->
    </body>
</html>

app.js

console.log('Define functions that make up app');

function DataService($http) {
    console.log('Setting up data service');
    var DataService = {};

    DataService.getData = function() {
        console.log('In DataService.getData, getting data');
        return $http.get('/data.json');
    };

    return DataService;
}

function DocumentCtrl(data) {
    console.log('In DocumentCtrl, check data');
    var self = this;
    self.data = data;
}

DocumentCtrl.resolve = {
    data: function(DataService) {
        console.log('Call DataService.getData()');
        return DataService.getData();
    },
}

function RouteConfig($routeProvider) {
    console.log('Define routes');
    $routeProvider
        .when('/', {
            template: "<h4>I'm in the content and above the data</h4><hr>{{docCtrl.data}}<hr><h4>I'm in the content and below the data</h4>",
            controllerAs: 'docCtrl',
            controller: 'DocumentCtrl',
            resolve: {
                data: function(DataService) {
                    console.log('Call DataService.getData()');
                    return DataService.getData();
                },
            }
        })
        .otherwise({ redirectTo: '/' })
}

console.log('Define module');

angular
    .module('app', ['ngRoute'])
    .factory('DataService', ['$http', DataService])
    .controller('DocumentCtrl', ['data', DocumentCtrl])
    .config(['$routeProvider', RouteConfig]);

person jordan.roskelley    schedule 15.09.2014    source источник
comment
попробуйте это в контроллере .controller('DocumentCtrl', ['DataService', DocumentCtrl])   -  person Seminda    schedule 15.09.2014


Ответы (3)


Добавление mangle:false к uglify.debugVendor.options, вероятно, исправит ситуацию. Если нет, то вам, вероятно, нужно скомпилировать файлы vendor и ваши файлы вместе, чтобы uglify мог использовать их в одной области видимости.

    uglify: {
        // ...
        debugVendor: {
            options: {
                mangle: false,
            },
        }
person Rob    schedule 15.09.2014

Имя вашей службы DataService, поэтому объявление в вашей конфигурации должно быть с тем же именем, например:

.controller('DocumentCtrl', ['DataService', DocumentCtrl])

Из вашего примера выше:

angular
    .module('app', ['ngRoute'])
    .factory('DataService', ['$http', DataService])
    .controller('DocumentCtrl', ['DataService', DocumentCtrl])
    .config(['$routeProvider', RouteConfig]);
person Dalorzo    schedule 15.09.2014
comment
Да, согласен с этим, ОП, см. примечание о минификации здесь docs.angularjs.org/tutorial/step_05 в качестве альтернативы используйте задачу ng-annotate grunt, чтобы сделать это за вас. - person shaunhusain; 15.09.2014
comment
В этом руководстве по стилю, на которое я ссылался, он говорит об использовании разрешения для получения данных перед вызовом контроллера вместо получения данных в контроллере: github.com/toddmotto/angularjs-styleguide#routing-resolves Я хочу, чтобы он разрешился до вызова контроллера. И кроме того, даже если я добавлю «DataService» в определение моего контроллера, он все равно ломается из-за искажения. - person jordan.roskelley; 15.09.2014

uglify изменить имя службы angularjs на a, b, .. . Поэтому вам нужно изменить параметры uglify:

options: {
    mangle: false,
},
person Mostafa    schedule 12.07.2015