【问题标题】:Module unrecognised in Angular while using Node & Mongo使用 Node 和 Mongo 时,Angular 无法识别模块
【发布时间】:2017-07-16 17:53:25
【问题描述】:

在一个足够原始的 MEAN-stack 项目上工作。 当我运行应用程序时,数据绑定失败,因为使我的视图和后端之间的关联(使 http 连接到我的数据库)的模块永远不会被实例化,并且无法识别。

控制台中出现以下错误消息

[$injector:modulerr] Failed to instantiate module moviesApp due to:
Error: [$injector:nomod] Module 'moviesApp' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.

错误信息是相当容易理解的。我似乎错误地(或根本没有)在“Movies.js”文件中创建了视图“MoviesList.html”和包含我上面提到的模块的文件(moviesApp)之间的链接。

Movies.js 使用了工厂。我检查了一般语法(看​​不到实际工厂中的错误代码如何导致模块无法识别)。之前在 jsfiddle 上写过一个基本的工厂,我相信语法应该没问题。 https://jsfiddle.net/Sheepy99/4wmd3zd0/(当然我在那个例子中链接了工厂,但这是相同的一般前提)

在我发布其余代码之前,它基于此处包含的示例:http://www.dotnetcurry.com/nodejs/1032/nodejs-apps-in-visual-studio-mean-stack 由于版本不同,我的一些代码有所不同,并且自作者发表文章以来,有些部分已被弃用(也想知道他为什么一直使用双双引号)。

任何含糊不清或松散的结局,问。

电影列表.html

<html>
<!--<meta charset="UTF-8">-->
<title>Node-Express Movie List</title>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<!--<link rel="stylesheet" href="/styles/site.css">-->
 
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script>
    <!--<script src="/scripts/controller.js"></script>
    <script src="/scripts/movies.js"></script>-->

    <script src="../public/scripts/movies.js"></script>
    <script src="../public/scripts/controller.js"></script>    
</head>


<body>    
    <div class="container">
        <!--<div class="text-center" ng-app="moviesApp" ng-controller="MoviesCtrl">-->
        <div class="text-center" ng-app="moviesApp" ng-controller="MoviesCtrl">
            <h1>Node-Express Movie List</h1>
            <div class="col-md-12" control-group="">
                <input type="text" style="width: 200px;" ng-model="newMovieText">
                <button id="btnAddTodo" class="btn" style="margin: 2px;" ng-click="addMovie()" ng-disabled="newMovieText">Add Movie</button>
            </div>
 
            <div class="col-md-5" sticky-note="">
                <h3 class="text-center">Released Movies</h3>
                <!--<div class="col-md-5" rowmargin="" todoitem="" ng-repeat="movie" in="" movies="" |="" filter:{released:true}"="">-->
                <div class="col-md-5" rowmargin="" todoitem="" ng-repeat="movie" in="" movies="" filter:{released:true}>
                    <div class="thumbnail">
                        <input type="checkbox" ng-model="movie.watched" ng-change="movieWatched(movie)">
                      
                        <span ng-class="{watchedMovie: movie.watched}">{{movie.name}}</span>
                    </div>
                </div>
            </div>
 
            <div class="col-md-5" sticky-note="">
                <h3 class="text-center">Coming Up...</h3>
                <div class="col-md-5" rowmargin="" todoitem="" ng-repeat="movie" in="" movies="" filter:{released:false}>
                    <div class="thumbnail">
                        {{movie.name}}
                        <br>
                        <br>
                        <input type="button" value="Released!" class="btn btn-success" btn-link="" released-button="" ng-click="movieReleased(movie)" style="">
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

movies.js

var app = angular.module('moviesApp', []);
 
app.factory('moviesCRUD', function ($http, $q) {
    function getAllMovies() {
        var deferred = $q.defer();
 
        $http.get('/api/movies').then(function (result) {
            deferred.resolve(result.data);
        }, function (error) {
            deferred.reject(error);
        });
 
        return deferred.promise;
    }
 
    function addMovie(newMovie) {
        var deferred = $q.defer();
 
        $http.post('/api/movies', newMovie).then(function (result) {
            deferred.resolve(result.data.movie);
        }, function (error) {
            deferred.reject(error);
        });
 
        return deferred.promise;
    }
 
    function modifyMovie(updatedMovie) {
        var deferred = $q.defer();
 
        $http.put('/api/movies/' + updatedMovie._id, updatedMovie).then(function (data) {
            deferred.resolve(data);
        }, function (error) {
            deferred.reject(error);
        });
 
        return deferred.promise;
    }
 
    return {
        getAllMovies: getAllMovies,
        addMovie: addMovie,
        modifyMovie: modifyMovie
    };
});

mongoOperations.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;  
//http://stackoverflow.com/questions/24908405/mongoose-and-new-schema-returns-referenceerror-schema-is-not-defined 
//link recommends use of what's on line 2 as a solution

mongoose.Promise = global.Promise; //not using promises, this line removes a default setting and also gets rid of a warning about promises
mongoose.connect('mongodb://localhost/moviesDb');
var db = mongoose.connection;

//var movieSchema = mongoose.Schema({  *I shouldn't need this because i've declared "require('mongoose')"
var movieSchema = new Schema({
name: String, //doesn't like if I have spaces on each new line, before the use of characters
released: Boolean,
watched: Boolean
});
var MovieModel = mongoose.model('movie', movieSchema);

db.on('error', console.error.bind(console, "connection error"));
db.once('open', function () {
    //console.log("moviesDb is open...");     
    MovieModel.find().exec(function (error, results) {
        if (results.length === 0) {
            MovieModel.create({ name: "The Amazing Spider-Man 2", released: true, watched: false });
            MovieModel.create({ name: "The Other Woman", released: true, watched: true });
            MovieModel.create({ name: "Shaadi ke Side Effects", released: false, watched: false });
            MovieModel.create({ name: "Walk of Shame", released: true, watched: false });
            MovieModel.create({ name: "Lucky Kabootar", released: false, watched: false });
        }
    });
});

exports.fetch = function (request, response) {
    MovieModel.find().exec(function (err, res) {
        if (err) {
             response.send(500, { error: err });
        }
        else {
            response.send(res);
        }
    });
};
exports.add = function (request, response) {
    var newMovie = { name: request.body.name, released: false, watched: false };
    MovieModel.create(newMovie, function (addError, addedMovie) {
        if (addError) {
            response.send(500, { error: addError });
        }
        else {
            response.send({ success: true, movie: addedMovie });
        }
    });
};
exports.modify = function (request, response) {
    var movieId = request.params.movieId;
    MovieModel.update({ _id: movieId }, { released: request.body.released, watched: request.body.watched }, { multi: false },
        function (error, rowsAffected) {
        if (error) {
            response.send(500, { error: error });
        }
        else if (rowsAffected == 0) {
            response.send(500, { error: "No rows affected" });
        }
        else {
            response.send(200);
        }
    }
);
};

server.js

var http = require('http');
var express = require('express');
var bodyParser = require('body-parser');
var path = require("path");
 
var port = process.env.port || 1337;
 
var app = express();
//app.use(bodyParser()); //getting deprecated warning in shell when using this specific line
app.use(bodyParser.urlencoded({ extended: true }));
//app.use(bodyParser.json()); used in stackoverflow solution, can see potential benefit, but isn't helping
var mongoOps = require('./server/MongoOperations.js');
 
app.get('/', function (request, response) {
    //response.sendfile("views/MoviesList.html");
    //response.sendFile("views/MoviesList.html");
    response.sendFile("views/MoviesList.html", { "root": __dirname });
});

app.get('/api/list', function (request, response) {
    response.send([{ id: 1, name: "charlie" }, { "id": 2, "name": "ward" }]);
        //'Hello World!');
});

app.get('/api/movies', mongoOps.fetch);
 
app.post('/api/movies', mongoOps.add);
 
app.put('/api/movies/:movieId', mongoOps.modify);


app.use(express.static(path.join(__dirname, 'public')));


app.listen(port);

controller.js

app.controller('MoviesCtrl', function ($scope, moviesCRUD) {
    $scope.released = { released: true };
    $scope.notReleased = { released: false };
     
    function init() {
        moviesCRUD.getAllMovies().then(function (movies) {
            $scope.movies = movies;
        }, function (error) {
            console.log(error);
        });        
    }
 
    $scope.movieReleased = function (movie) {
 
        moviesCRUD.modifyMovie({ _id: movie._id, name: movie.name, released: true, watched: movie.watched })
                  .then(function (result) {
                      if (result.status === 200) {
                          movie.released = true;
                      }
                  }, function (error) {
                      console.log(error);
                  });        
    };
 
    $scope.movieWatched = function (movie) {
        moviesCRUD.modifyMovie(movie)
                  .then(function (result) {
                      if (result.status === 200) {
                          console.log("Movie updated");
                      }
                  }, function (error) {
                      movie.watched = !movie.watched;
                  });        
    };
 
    $scope.addMovie = function () {
        moviesCRUD.addMovie({ name: $scope.newMovieText }).then(function (newMovie) {
            $scope.movies.push(newMovie);
            $scope.newMovieText = "";
        }, function (error) {
            console.log(error);
        });        
    };
 
    init();
});

此外,我的大部分 html 都在菱形内呈现为问号。这让我非常困惑。只是想我会把它放在那里。

作为菜鸟,任何简短的一般性建议都将受到欢迎,例如调整我的代码以提高可读性或方法。

【问题讨论】:

    标签: javascript angularjs node.js mongodb mean-stack


    【解决方案1】:

    我对您的代码进行了一些更改以让 Angular “编译”它,但我没有控制器的代码,因此无法完成设置。但是如果你看看这个plunk,你可以看到我的变化。

    <html ng-app="moviesApp">
    
      <head>
        <!--<meta charset="UTF-8">-->
        <title>Node-Express Movie List</title>
        <script data-require="angular.js@1.6.1" data-semver="1.6.1" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>
        <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
        <!--<link rel="stylesheet" href="/styles/site.css">-->
        <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script>
        <!--<script src="/scripts/controller.js"></script>
        <script src="/scripts/movies.js"></script>-->
        <script src="movies.js"></script>
        <!--<script src="../public/scripts/controller.js"></script>-->
      </head>
    

    您在 HTML 中放置 HEAD 时遇到了问题,而且您在第一个 DIV 中引导了应用程序,我猜它可以工作,但它非常不标准。您可以在 Plunk 或 Codepen 中启动您的应用程序,以使您自己更轻松。

    玩得开心。

    【讨论】:

      【解决方案2】:

      想通了:

      因为我在 server.js 的底部附近有以下行,所以当为外部模块(在本例中为 controller.js 和 movies.js)指定指令时,我的目录会自动启动 public。 因此,我的指示是不正确的。 至于我在问题底部提到的奇怪的菱形,这是因为我的文件在我创建它们时被自动保存为 ASCII,而它们本来应该是 UTF-8。

      一个令人讨厌和迂腐的问题,但我相信最终有人会从中找到一些帮助。

      app.use(express.static(path.join(__dirname, 'public')));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-24
        • 1970-01-01
        • 2018-07-28
        • 2022-01-22
        • 2021-11-01
        • 2016-07-08
        • 2023-03-19
        • 1970-01-01
        相关资源
        最近更新 更多