到期

时间:2016-06-21 09:08:55

标签: javascript angularjs ionic-framework

我一直收到这个错误,我不明白为什么:

  

错误:[$ injector:modulerr]无法实例化模块启动器到期   to:[$ injector:modulerr]无法实例化模块   starter.controllers由于:[$ injector:modulerr]无法实例化   模块starter.services由于:[$ injector:nomod]模块   ' starter.services'不可用!你要么拼错了模块   命名或忘记加载它。如果注册模块,请确保您   将依赖项指定为第二个参数。

calendar.html文件:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
    <link href="lib/ionic/css/ionic.css" rel="stylesheet">
    <link href="css/style.css" rel="stylesheet">
    <script src="lib/ionic/js/ionic.bundle.js"></script>
    <!-- cordova script (this will be a 404 during development) -->
    <script src="cordova.js"></script>
    <!-- your app's js -->
    <script src="js/app.js"></script>
    <script src="js/controllers.js"></script>
    <script src="js/services.js"></script>
</head>
<body ng-app="starter">
<ion-pane ng-controller="CalendarCtrl">
    <ion-content>

        <div class="card" ng-repeat="event in events">
            <div class="item item-divider">
                {{event.title}}
            </div>
            <div class="item item-text-wrap">
                {{ event.description }}
                <p/>
                <strong>When: {{ event.date | date:'short' }}</strong>
            </div>
        </div>

    </ion-content>
</ion-pane>
</body>
</html>

services.js文件:

angular.module('starter.services', [])

    .factory('Events', function($q) {

        var incrementDate = function (date, amount) {
            var tmpDate = new Date(date);
            tmpDate.setDate(tmpDate.getDate() + amount)
            return tmpDate;
        };

        //create fake events, but make it dynamic so they are in the next week
        var fakeEvents = [];
        fakeEvents.push(
            {
                "title":"Meetup on Ionic",
                "description":"We'll talk about beer, not Ionic.",
                "date":incrementDate(new Date(), 1)
            }
        );
        fakeEvents.push(
            {
                "title":"Meetup on Beer",
                "description":"We'll talk about Ionic, not Beer.",
                "date":incrementDate(new Date(), 2)
            }
        );
        fakeEvents.push(
            {
                "title":"Ray's Birthday Bash",
                "description":"Celebrate the awesomeness of Ray",
                "date":incrementDate(new Date(), 4)
            }
        );
        fakeEvents.push(
            {
                "title":"Code Review",
                "description":"Let's tear apart Ray's code.",
                "date":incrementDate(new Date(), 5)
            }
        );

        var getEvents = function() {
            var deferred = $q.defer();
            deferred.resolve(fakeEvents);
            return deferred.promise;
        }

        return {
            get:getEvents
        };

    });

controller.js文件:

angular.module('starter.controllers', ['starter.services'])

.controller('AppCtrl', function ($scope, $ionicModal, $timeout) {

    // With the new view caching in Ionic, Controllers are only called
    // when they are recreated or on app start, instead of every page change.
    // To listen for when this page is active (for example, to refresh data),
    // listen for the $ionicView.enter event:
    //$scope.$on('$ionicView.enter', function(e) {
    //});

    // Form data for the login modal
    $scope.loginData = {};

    // Create the login modal that we will use later
    $ionicModal.fromTemplateUrl('templates/login.html', {
        scope: $scope
    }).then(function (modal) {
        $scope.modal = modal;
    });

    // Triggered in the login modal to close it
    $scope.closeLogin = function () {
        $scope.modal.hide();
    };

    // Open the login modal
    $scope.login = function () {
        $scope.modal.show();
    };

    // Perform the login action when the user submits the login form
    $scope.doLogin = function () {
        console.log('Doing login', $scope.loginData);
        // Simulate a login delay. Remove this and replace with your login
        // code if using a login system
        $timeout(function () {
            $scope.closeLogin();
        }, 1000);
    };
})


.controller('CalendarCtrl', ['starter.services', function ($scope, Events) {

    Events.get().then(function (events) {
        console.log("events", events);
        $scope.events = events;
    })
}])

.controller('PlaylistsCtrl', function ($scope) {
    $scope.playlists = [
        {title: 'Reggae', id: 1},
        {title: 'Chill', id: 2},
        {title: 'Dubstep', id: 3},
        {title: 'Indie', id: 4},
        {title: 'Rap', id: 5},
        {title: 'Cowbell', id: 6}
    ];
})


.controller('PlaylistCtrl', function ($scope, $stateParams) {
});

app.js文件:

// Ionic Starter App

// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
// 'starter.controllers' is found in controllers.js
angular.module('starter', ['ionic', 'starter.controllers','starter.services'])

    .run(function ($ionicPlatform) {
        $ionicPlatform.ready(function () {
            // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
            // for form inputs)
            if (window.cordova && window.cordova.plugins.Keyboard) {
                cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
                cordova.plugins.Keyboard.disableScroll(true);

            }
            if (window.StatusBar) {
                // org.apache.cordova.statusbar required
                StatusBar.styleDefault();
            }
        });
    })

    .config(function ($stateProvider, $urlRouterProvider) {
        $stateProvider

            .state('app', {
                url: '/app',
                abstract: true,
                templateUrl: 'templates/menu.html',
                controller: 'AppCtrl'
            })

            .state('app.search', {
                url: '/search',
                views: {
                    'menuContent': {
                        templateUrl: 'templates/search.html'
                    }
                }
            })

            .state('app.browse', {
                url: '/browse',
                views: {
                    'menuContent': {
                        templateUrl: 'templates/browse.html'
                    }
                }
            })

            .state('app.calendar', {
                url: '/calendar',
                views: {
                    'menuContent': {
                        templateUrl: 'templates/calendar.html',
                        controller: 'CalendarCtrl'
                    }
                }
            })

            .state('app.playlists', {
                url: '/playlists',
                views: {
                    'menuContent': {
                        templateUrl: 'templates/playlists.html',
                        controller: 'PlaylistsCtrl'
                    }
                }
            })

            .state('app.single', {
                url: '/playlists/:playlistId',
                views: {
                    'menuContent': {
                        templateUrl: 'templates/playlist.html',
                        controller: 'PlaylistCtrl'
                    }
                }
            });
        // if none of the above states are matched, use this as the fallback
        $urlRouterProvider.otherwise('/app/playlists');
    });

5 个答案:

答案 0 :(得分:4)

首先,您将calendar.htmlindex.html混为一谈。我建议您将index.htmlcalendar.html分开。

app.js中的starter.controllers注入因此而引发错误。

其次,在starter.services中注入app.js之后,您不需要在创建的每个控制器文件中注入它,尽管它不会抛出错误。

第三,在这种情况下,将starter.services工厂注入控制器是错误的。您的services.js代码很好。我已将 app.js 更改为直接指向日历页面。

按照以下说明,你很高兴:

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
    <title></title>

    <link href="lib/ionic/css/ionic.css" rel="stylesheet">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">

    <link href="css/style.css" rel="stylesheet">

    <!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
    <link href="css/ionic.app.css" rel="stylesheet">
    -->

    <!-- ionic/angularjs js -->
    <script src="lib/ionic/js/ionic.bundle.js"></script>

    <!-- cordova script (this will be a 404 during development) -->
    <script src="cordova.js"></script>

    <!-- your app's js -->
    <script src="js/app.js"></script>
    <script src="js/controllers/controllers.js"></script>
    <script src="js/services.js"></script>
  </head>

  <body ng-app="starter">
    <ion-nav-view></ion-nav-view>
  </body>
</html>

calendar.html

<ion-pane ng-controller="CalendarCtrl">
    <ion-content>

        <div class="card" ng-repeat="event in events">
            <div class="item item-divider">
                {{event.title}}
            </div>
            <div class="item item-text-wrap">
                {{ event.description }}
                <p/>
                <strong>When: {{ event.date | date:'short' }}</strong>
            </div>
        </div>

    </ion-content>
</ion-pane>

controller.js

angular.module('starter.controllers', [])

.controller('AppCtrl', function ($scope, $ionicModal, $timeout) {

    // With the new view caching in Ionic, Controllers are only called
    // when they are recreated or on app start, instead of every page change.
    // To listen for when this page is active (for example, to refresh data),
    // listen for the $ionicView.enter event:
    //$scope.$on('$ionicView.enter', function(e) {
    //});

    // Form data for the login modal
    $scope.loginData = {};

    // Create the login modal that we will use later
    $ionicModal.fromTemplateUrl('templates/login.html', {
        scope: $scope
    }).then(function (modal) {
        $scope.modal = modal;
    });

    // Triggered in the login modal to close it
    $scope.closeLogin = function () {
        $scope.modal.hide();
    };

    // Open the login modal
    $scope.login = function () {
        $scope.modal.show();
    };

    // Perform the login action when the user submits the login form
    $scope.doLogin = function () {
        console.log('Doing login', $scope.loginData);
        // Simulate a login delay. Remove this and replace with your login
        // code if using a login system
        $timeout(function () {
            $scope.closeLogin();
        }, 1000);
    };
})


.controller('CalendarCtrl', function ($scope, Events) {

    Events.get().then(function (events) {
        console.log("events", events);
        $scope.events = events;
    })
})

.controller('PlaylistsCtrl', function ($scope) {
    $scope.playlists = [
        {title: 'Reggae', id: 1},
        {title: 'Chill', id: 2},
        {title: 'Dubstep', id: 3},
        {title: 'Indie', id: 4},
        {title: 'Rap', id: 5},
        {title: 'Cowbell', id: 6}
    ];
})


.controller('PlaylistCtrl', function ($scope, $stateParams) {
});  

app.js

// Ionic Starter App

// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
// 'starter.controllers' is found in controllers.js
angular.module('starter', ['ionic', 'starter.controllers','starter.services'])

    .run(function ($ionicPlatform) {
        $ionicPlatform.ready(function () {
            // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
            // for form inputs)
            if (window.cordova && window.cordova.plugins.Keyboard) {
                cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
                cordova.plugins.Keyboard.disableScroll(true);

            }
            if (window.StatusBar) {
                // org.apache.cordova.statusbar required
                StatusBar.styleDefault();
            }
        });
    })

    .config(function ($stateProvider, $urlRouterProvider) {
        $stateProvider

            .state('app', {
                url: '/app',
                abstract: true,
                templateUrl: 'templates/menu.html',
                controller: 'AppCtrl'
            })

            .state('app.search', {
                url: '/search',
                views: {
                    'menuContent': {
                        templateUrl: 'templates/search.html'
                    }
                }
            })

            .state('app.browse', {
                url: '/browse',
                views: {
                    'menuContent': {
                        templateUrl: 'templates/browse.html'
                    }
                }
            })

            .state('app.calendar', {
                url: '/calendar',
                views: {
                    'menuContent': {
                        templateUrl: 'templates/calendar.html',
                        controller: 'CalendarCtrl'
                    }
                }
            })

            .state('app.playlists', {
                url: '/playlists',
                views: {
                    'menuContent': {
                        templateUrl: 'templates/playlists.html',
                        controller: 'PlaylistsCtrl'
                    }
                }
            })

            .state('app.single', {
                url: '/playlists/:playlistId',
                views: {
                    'menuContent': {
                        templateUrl: 'templates/playlist.html',
                        controller: 'PlaylistCtrl'
                    }
                }
            });
        // if none of the above states are matched, use this as the fallback
        $urlRouterProvider.otherwise('/app/calendar');
    });

答案 1 :(得分:1)

请在calendar.html中更改以下脚本的顺序

 <script src="js/app.js"></script>
    <script src="js/controllers.js"></script>
    <script src="js/services.js"></script>

 <script src="js/controllers.js"></script>
    <script src="js/services.js"></script>
 <script src="js/app.js"></script>

让我知道如果这不起作用你也可以提供jsfiddle,我可以帮助你。

如果这解决了我可以解释模块应该首先注册然后应该在任何地方使用。

我的意思是这将像变量一样工作,而不是悬挂。如果我们在执行此操作之前在模块B中注入/使用模块A,我们必须注册模块A,这就是我们需要在此处更改订单的原因。

答案 2 :(得分:0)

检查您的控制器

angular.module('starter.controllers', ['starter.services'])

应该是这样的

angular.module('starter.controllers', [])

并检查您的index.html是否已包含所有 .js 文件

改变它会帮助你

答案 3 :(得分:0)

您发布的代码相当无关紧要,错误清楚地说明了错误

应用程序引导时starter.services不可用

未加载services.js(检查开发者工具中的网络标签)或加载顺序错误(最有可能)

一旦加载匹配ng-app的模块,angular将引导应用程序,因此您可以重新排序文件,以便在app.js之前加载服务和控制器

OR

您可以使用gulp或grunt自动化,将所需的所有文件连接到一个

OR

你可以从你的html中删除ng-app并在头部或身体的底部添加以下行来手动引导

<script>
  angular.element(document).ready(function() {
    angular.bootstrap(document, ['starter']);
  });
</script>

这样的文件顺序无关紧要

答案 4 :(得分:0)

如果您遇到过此类错误,请确保已将htmls中引用的js和其他资源添加到带有绝对路径的index.html文件中。

这是对任何寻求解决此类问题的人的抽象答案。

希望这有帮助。