目前我正在尝试使用socket.io和angular.js实现实时内容,据我所知,我做的一切都是正确的,但实时不起作用。也许我错过了任何重要的事情。
我将写一个关于它应该如何工作的场景。基本上用户编写内容然后将值发布到服务器。在home.html中,内容应该是实时的(我已将所有内容放在包括home.html)。
这是代码
server.js
var express = require('express');
var app = express();
var morgan = require('morgan');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var path = require('path');
var config = require('./config');
// REAL TIME WORK
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization');
next();
});
// log our request to our terminal
app.use(morgan('dev'));
// Connect to our database using mongoose
mongoose.connect(config.database, function(err) {
if(err) {
console.log("Connection to a mongodb database has failed");
} else {
console.log("Connected to a database");
}
});
// set our static files to a designated location
app.use(express.static(__dirname + '/public'));
var apiRouter = require('./app/routes/api') (app, express, io);
app.use('/api', apiRouter);
// registered before your api routes.
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname + '/public/app/views/index.html'));
});
http.listen(config.port, function(err) {
if(err) {
console.log("There's an error connecting the app to port" + config.port);
} else {
console.log("App is listening on port " + config.port);
}
});
api.js
module.exports = function(app, express, io) {
// creating our first router
var apiRouter = express.Router();
// signup a user
var createStory = function(req, res) {
var story = new Story({
user: req.decoded.id,
content: req.body.content
});
story.save(function(err) {
if(err) {
res.send(err);
return;
}
io.emit('story', req.body.content);
res.json({ message: 'Story has been created!'});
});
};
apiRouter.route('/')
.post(createStory)
.get(function(req, res) {
Story.find({ user: req.decoded.id }, function(err, story) {
if(err) {
res.send(err);
return;
}
res.json(story);
});
});
service.js
angular.module('storyService', [])
.factory('Story', function($http, $window) {
// get all approach
var storyFactory = {};
var generateReq = function(method, url, data) {
var req = {
method: method,
url: url,
headers: {
'x-access-token': $window.localStorage.getItem('token')
},
cache: false
}
if(method === 'POST') {
req.data = data;
}
return req;
};
storyFactory.all = function() {
return $http(generateReq('GET', '/api/'));
};
storyFactory.create = function(storyData) {
return $http(generateReq('POST', '/api/', storyData));
};
storyFactory.getSingleStory = function(user_name, story_id) {
return $http(generateReq('GET', '/api/' + user_name + '/' + story_id));
};
storyFactory.allStories = function() {
return $http(generateReq('GET', '/api/all_stories'));
};
return storyFactory;
})
.factory('socketio', ['$rootScope', function ($rootScope) {
var socket = io.connect();
return {
on: function (eventName, callback) {
socket.on(eventName, function () {
var args = arguments;
$rootScope.$apply(function () {
callback.apply(socket, args);
});
});
},
emit: function (eventName, data, callback) {
socket.emit(eventName, data, function () {
var args = arguments;
$rootScope.$apply(function () {
if (callback) {
callback.apply(socket, args);
}
});
});
}
};
}]);
controller.js
angular.module('storyCtrl', ['storyService'])
.controller('StoryController', function(Story, $routeParams, $scope, socketio) {
var vm = this;
Story.all()
.success(function(data) {
$scope.stories = data;
});
Story.getSingleStory($routeParams.user_name, $routeParams.story_id)
.success(function(data) {
$scope.storyData = data;
});
vm.createStory = function() {
vm.message = '';
Story.create(vm.storyData)
.success(function(data) {
// clear the form
vm.storyData = {}
vm.message = data.message;
socketio.on('story', function () {
$scope.stories.push(data);
});
});
};
});
的index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>User Diary</title>
<base href="/">
<!-- CSS -->
<!-- load bootstrap from CDN and custom CSS -->
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootswatch/3.3.1/paper/bootstrap.min.css">
<!-- load angular and angular-route via CDN -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-route.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.12.0/ui-bootstrap-tpls.js"></script>
<!-- directives -->
<!--controllers -->
<script src="app/controllers/storyCtrl.js"></script>
<script src="app/services/storyService.js"></script>
<!-- main Angular app files -->
<script src="app/app.routes.js"></script>
<script src="app/app.js"></script>
</head>
<body ng-app="userApp">
<main class="container">
<!-- ANGULAR VIEWS -->
<div ng-view></div>
</main>
</body>
</html>
home.html的
<div class="panel-body" ng-repeat="story in stories | reverse" >
<ul class="list-group">
<li class="list-group-item">
<div class="row">
<div class="col-xs-10 col-md-11">
<div>
<div class="mic-info">
{{ story.createdAt | date:'MMM d, yyyy' }}
</div>
</div>
<div class="comment-text">
<h4>{{ story.content }}</h4>
</div>
</div>
</div>
</li>
</ul>
</div>
我知道它很大,我发布这一切的原因是因为我不想错过任何事情。
我对这整个socket.io + angular.js真的很陌生,如果你有任何意见可以教我一些关于socket.io + angular.js的意见,这对我来说意味着很多:)
答案 0 :(得分:2)
继续发表评论。
只需要创建一次事件监听器socketio.on(..)
。它会在删除之前收到所有未来事件。另请注意,不要混用vm
和$scope
angular.module('storyCtrl', ['storyService'])
.controller('StoryController', function(Story, $routeParams, socketio) {
var vm = this;
vm.stories = [];
Story.all()
.success(function(data) {
vm.stories = data;
});
Story.getSingleStory($routeParams.user_name, $routeParams.story_id)
.success(function(data) {
vm.storyData = data;
});
vm.createStory = function() {
vm.message = '';
Story.create(vm.storyData)
.success(function(data) {
// clear the form
vm.storyData = {}
vm.message = data.message;
});
};
socketio.on('story', function (data) {
vm.stories.push(data);
});
});
创建ng-controller="StoryController as StoryCtrl"
之类的控制器并重复ng-repeat="story in StoryCtrl.stories"
您的服务器端发出时只响应帖子内容,因为它似乎应该返回至少具有content
和createdAt
属性的对象
// signup a user
var createStory = function(req, res) {
var story = new Story({
user: req.decoded.id,
content: req.body.content
});
story.save(function(err) {
if(err) {
res.send(err);
return;
}
io.emit('story', {
user: req.decoded.id,
createdAt: new Date(),
content: req.body.content
});
// you might be able to do instead
// io.emit('story', story.toObject())
res.json({ message: 'Story has been created!'});
});
};