所以我有這個基於AngularJS的基礎CRUD Todo應用程序。然後我想我想用一些Socket.IO來使它成爲一個實時的Web應用程序。但是,我有一些問題讓它正常工作。AngularJS + Socket.IO - 如何更新模型?
設置: 約曼(涼亭+咕嚕) AngularJS RequireJS +的NodeJS MongoDB的 Socket.IO
我'咕嚕服務器的運行在localhost:9000,而我的NodeJS /的MongoDB/Socket.IO服務器運行on localhost:4711
目前,Socket.IO的作用是創建和刪除待辦事項,但我似乎無法弄清楚如何更新我的待辦事項。我認爲會很容易。
這裏是codez。
Socket.js:
var io = require('socket.io');
exports.initialize = function(server) {
io = io.listen(server);
io.sockets.on('connection', function(socket) {
socket.on('message', function(message) {
message = JSON.parse(message);
socket.get('deletedTodo', function(err, nickname) {
socket.broadcast.send(JSON.stringify(message));
socket.send(JSON.stringify(message));
});
});
socket.on('delete_todo', function(data) {
socket.set('deletedTodo', data.title, function() {
socket.emit('todo_delete', data);
socket.broadcast.emit('todoDeleted', data);
});
});
socket.on('update_todo', function(data) {
socket.broadcast.emit('todoUpdated', data);
})
});
}
這裏是我的客戶端codez。
Services.js:
/*global define*/
define(['angular'], function(angular) {
'use strict';
return angular.module('services', [])
.factory('Todo', function($resource) {
//var baseUrl = 'http://designit-todo.eu01.aws.af.cm/api/todos/:id';
var baseUrl = 'http://localhost:port/api/todos/:id';
return $resource(baseUrl,
{port: ':4711', id: '@_id'}, {
'update': {method:'PUT'},
'delete': {method:'DELETE', isArray: true}
});
})
.factory('socket', function($rootScope) {
var socket = io.connect('http://localhost:4711');
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);
}
});
});
},
send: function(eventName, data, callback) {
socket.send(eventName, data, function() {
var args = arguments;
$rootScope.$apply(function() {
if (callback) {
callback.apply(socket, args);
}
});
});
}
}
});
});
Controllers.js:
/*global define*/
define(['angular', 'services/services'], function(angular) {
'use strict';
return angular.module('controllers', ['services'])
.controller('Todos', ['$scope', '$resource', 'Todo', '$location', 'socket', function($scope, $resource, Todo, $location, socket) {
// Grab all todos.
$scope.todos = Todo.query();
socket.on('message', function(data) {
// Grab all todos when new added via socket.
$scope.todos = Todo.query();
$scope.todos.push(data);
});
// Complete/update todo.
$scope.todoCompleted = function(todo) {
todo.$update();
socket.emit('update_todo', todo);
}
socket.on('todoUpdated', function(todo) {
// Update on all connected clients.
console.log(todo);
});
$scope.removeTodo = function(todo) {
var index = $scope.todos.indexOf(todo);
socket.emit("delete_todo", JSON.stringify(index));
$scope.todos.splice(index, 1);
todo.$remove();
}
socket.on('todoDeleted', function(index) {
$scope.todos.splice(index, 1);
});
}])
.controller('Single', ['$scope', '$resource', '$routeParams', 'Todo', '$timeout', '$location', function($scope, $resource, $routeParams, Todo, $timeout, $location) {
// Grab just a single todo
$scope.todo = Todo.get({ id: $routeParams.id });
// Throttle the update PUT request
var saveTimeout;
$scope.save = function() {
$timeout.cancel(saveTimeout);
saveTimeout = $timeout(function() {
// Save the todo and then update the scope
$scope.todo.$update(function(updated_todo) {
$scope.todo = updated_todo;
});
}, 1000);
};
}])
.controller('Add', ['$scope', '$resource', 'Todo', '$location', 'socket', function($scope, $resource, Todo, $location, socket) {
$scope.todo = new Todo({});
$scope.save = function() {
if ($scope.todo.title) {
$scope.todo.$save(function(data) {
console.log(data);
socket.send(JSON.stringify(data));
$location.path('/');
});
}
}
}]);
});
所以我的問題是這樣的一段代碼中:
// Complete/update todo.
$scope.todoCompleted = function(todo) {
todo.$update();
socket.emit('update_todo', todo);
}
socket.on('todoUpdated', function(todo) {
// Update on all connected clients.
console.log(todo);
});
當我CONSOLE.LOG(待辦事項),我收到了待辦事項,但我可以對其進行「todo。$ update」。我也試過類似:
socket.on('todoUpdated', function(todo) {
var thisTodo = Todo.get({id: todo._id});
console.log(thisTodo);
});
但只要我嘗試做thisTodo $更新()我得到一個錯誤:
PUT http://localhost:4711/api/todos 404 (Not Found) :4711/api/todos:1
我在做什麼錯?如果我在我的代碼中做了任何錯誤,請糾正我。我對AngularJS和Socket.IO還是比較新的。
的問題不在於socket.io,一切都似乎工作。問題在於你的API。顯然,你正在嘗試使用'id'' 1'更新待辦事項,但服務器似乎無法找到這個待辦事項。測試你的API的好工具是郵差:https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm/ – RoryKoehein
嗯..我不認爲這是錯誤的我的API?我已經嘗試過使用高級Rest Rest Client for Chrome,並且GET,POST,PUT DELETE在http:// localhost:4711/api/todos上正常工作 – dgsunesen
檢查以瞭解Angular嘗試執行的確切PUT請求在你的開發工具中,並將其與你正在使用Rest Client進行的請求進行比較。那麼PUT請求肯定有問題。 – RoryKoehein