Angularjs 包含node.js和angular.js的简单目录列表,查看新文件

Angularjs 包含node.js和angular.js的简单目录列表,查看新文件,angularjs,node.js,Angularjs,Node.js,我已经成功地创建了一个简单的angular应用程序,它列出了文件夹的文件内容(使用一个吐出json的节点端点)。我现在想做的是,如果一个新文件被添加到文件夹中,以某种方式得到通知。我需要这两个服务器和客户端 server.js: var express = require('express'), fs = require('fs'), path = require('path'); var app = express(); function dirTree(filename)

我已经成功地创建了一个简单的angular应用程序,它列出了文件夹的文件内容(使用一个吐出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);
    });
});
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...');    
});
<!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>
角度控制器:

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);
    });
});
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...');    
});
<!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>
这是完美的。但是,如果文件夹中添加了新文件,则需要刷新页面。是的,代码没有涵盖这一点,实现也非常简单(在控制器init上使用一次性get请求是不够的)

那么,究竟如何才能做到这一点呢?节点端应该有一个监听器,它会以某种方式发出angular可以捕获的事件(?)

  • 如何在node.js中侦听“新文件添加”
  • 如何在节点和角节点(可能是套接字)之间发出事件/通信
  • 欢迎所有观察

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

    PS2:express 4.x已被使用

    是一条路要走

    • 本例使用,因此在开始之前,请确保
      npm安装--save socket.io
    • 原始的dirTree和jsonp回调保持不变
    • angular请求在回调中使用常规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);
        });
    });
    
    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...');    
    });
    
    <!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>
    
    因此,我们主要只是添加websocket侦听器。它等待连接,然后使用节点的内置方法。当检测到更改时,它使用现有的
    dirTree
    方法构造一条消息,然后发送给客户端

    index.html:

    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);
        });
    });
    
    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...');    
    });
    
    <!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>
    
    
    angular.module('myApp',[])
    .controller('PageCtrl',函数($scope,$http){
    $http.get('/').success(函数(数据、状态、标题、配置){
    $scope.files=data.children;
    var socket=io.connect();
    socket.on('change',函数(msg){
    $scope.files.push(msg);
    $scope.$digest();
    });
    }).error(函数(数据、状态、标题、配置){
    log(数据、状态、标题、配置);
    });
    });
    
    • {{f}
    在这里,我们只需要使用socket.io连接到我们在
    server.js
    中创建的webocket侦听器,侦听
    change
    消息,并将它们推送到已由初始json请求填充的现有
    $scope.files
    数组中

    此示例还缺少文件重命名和删除所需处理的一些其他消息,以及递归工作的能力


    注意:除了这样的概念验证代码之外,不要实际使用node的fs.watch api。如果您阅读文档,您将看到它在不同平台上的行为有所不同。强烈建议使用第三方文件监视模块,例如。

    那么,将您的请求放入$timeout中,并使用一个服务器端逻辑,该逻辑将被调用,如果新文件到达,只需返回一个包含您想要返回的任何内容的响应就行了吗?我假设您的意思是$interval,您的意思是轮询服务器以获取新数据?您可以轮询,但也可以使用websockets@dekztah是的,对不起。我想情况并非如此。WebSocket是正确的方法,不幸的是我不能使用它们,我希望有人能添加一个答案来了解更多…工作起来很有魅力,尽管我必须承认我一开始做错了(端口9000的grunt服务和端口9000的socket io GET请求因此失败)。非常感谢你!