使用node.js和angular.js列出简单目录,查看新文件

时间:2015-12-12 16:12:02

标签: angularjs node.js

我设法创建了一个简单的角度应用程序,它列出了文件夹的文件内容(使用一个吐出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);
    });
});

这完美无瑕。但是,如果将新文件添加到文件夹,则需要刷新页面。是的,代码不包括这个,并且实现也非常小(在控制器初始化上使用一次性获取请求不够)。

那么一个人怎么做呢?节点端应该有一个监听器,它会以某种方式发出一个角度可以捕获的事件(?)

  1. 我如何倾听"新文件添加"在node.js
  2. 如何在节点和角度(可能是套接字)之间发出事件/通信
  3. 欢迎所有观察!

    PS:我不想混合使用服务器端和客户端逻辑!我需要一个干净的沟通解决方案/最佳实践

    PS2:快递4.x使用

1 个答案:

答案 0 :(得分:1)

Websockets是要走的路。

  • 此示例使用socket.io,因此在开始之前,请确保npm install --save socket.io
  • 原始dirTree和jsonp回调保持不变
  • 角度请求在回调中使用常规json

<强> 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