我设法创建了一个简单的角度应用程序,它列出了文件夹的文件内容(使用一个吐出json的节点端点)。我现在要做的是以某种方式获得通知,如果新文件添加到该文件夹。我需要在服务器端和客户端都这样做。
server.js:
var express = require('express'),
fs = require('fs'),
path = require('path');
var app = express();
function dirTree(filename) {
var stats = fs.lstatSync(filename),
info = {
path: filename,
name: path.basename(filename)
};
if (stats.isDirectory()) {
info.type = "folder";
info.children = fs.readdirSync(filename).map(function(child) {
return dirTree(filename + '/' + child);
});
} else {
info.type = "file";
}
return info;
}
app.set('jsonp callback', true);
app.get('/', function(req, res) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Charset','utf-8');
res.header('Content-Type', 'application/json');
var jsonp_callback = app.get('jsonp callback name');
var jsonp = (req.query[jsonp_callback]);
var result = dirTree('files');
if (jsonp) {
res.jsonp(result);
}
else {
res.json(result);
}
});
app.listen(3001);
console.log('Listening on port 3001...');
角度控制器:
'use strict';
angular.module('myApp').controller('PageCtrl', function($scope, folderUrl, $http) {
$http.jsonp(folderUrl).success(function(data, status, headers, config) {
console.log(data);
$scope.files = data.children;
}).error(function(data, status, headers, config) {
console.log(data, status, headers, config);
});
});
这完美无瑕。但是,如果将新文件添加到文件夹,则需要刷新页面。是的,代码不包括这个,并且实现也非常小(在控制器初始化上使用一次性获取请求不够)。
那么一个人怎么做呢?节点端应该有一个监听器,它会以某种方式发出一个角度可以捕获的事件(?)。
欢迎所有观察!
PS:我不想混合使用服务器端和客户端逻辑!我需要一个干净的沟通解决方案/最佳实践
PS2:快递4.x使用
答案 0 :(得分:1)
Websockets是要走的路。
npm install --save socket.io
。<强> server.js:强>
var http = require('http'),
express = require('express'),
fs = require('fs'),
path = require('path');
var app = express();
var server = http.createServer(app);
function dirTree(filename) {
...
}
app.set('jsonp callback', true);
app.get('/', function(req, res) {
...
});
app.get('/index.html', function (req, res) {
res.sendfile('index.html');
});
var io = require('socket.io').listen(server);
io.sockets.on('connection', function(socket) {
var watcher = fs.watch('files', function (event, filename) {
if (fs.existsSync('files/' + filename)) {
socket.emit('change', dirTree('files/' + filename));
}
});
socket.on('disconnect', function() {
watcher.close();
});
});
server.listen(3001, function() {
console.log('Listening on port 3001...');
});
所以我们主要只是添加websocket监听器。它等待连接,然后使用fs.watch方法内置的节点。当它检测到更改时,它使用现有的dirTree
方法构造一条消息,然后将其发送给客户端。
<强>的index.html:强>
<!doctype html>
<html ng-app="myApp">
<head>
<script src="/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script>
angular.module('myApp', [])
.controller('PageCtrl', function($scope, $http) {
$http.get('/').success(function(data, status, headers, config) {
$scope.files = data.children;
var socket = io.connect();
socket.on('change', function(msg) {
$scope.files.push(msg);
$scope.$digest();
});
}).error(function(data, status, headers, config) {
console.log(data, status, headers, config);
});
});
</script>
</head>
<body>
<div ng-controller="PageCtrl">
<ul><li ng-repeat="f in files">{{f}}</li></ul>
</div>
</body>
</html>
这里我们只需要使用socket.io来连接我们在server.js
中创建的webocket监听器,监听change
消息,然后将它们推送到现有的$scope.files
数组中。 ; s已经被初始的json请求填充。
此示例还缺少您需要处理文件重命名和删除的一些其他消息,以及递归工作的能力。
注意:实际上并没有使用节点的fs.watch api来获取除此类概念代码之外的任何其他内容。如果您阅读了文档,您会发现它从一个平台到另一个平台的行为有所不同。强烈建议使用第三方文件观看模块,例如watch。