我目前正在开发一个聊天网络应用。这应该被实现为单页面应用程序。为此,我使用Angular Router。我使用socket-io将消息从客户端发送到服务器。在路线之间导航实际上非常有效。
在路由home.html
中,有一个输入元素用于输入消息。单击该按钮后,它将作为<li>
列表中的<ul>
元素添加并显示。启动应用程序时,我可以正常编写消息。但是,如果我从家庭路线导航到另一条路线然后返回家并输入消息,它将被发送两次。下次你来回导航三次,依此类推。好像控制器正在运行几次。
我无法在互联网上找到解决此问题的方法。但无论如何都必须这样做。
P.S:我只在index.html
中包含了一个脚本文件,因为我使用gulp将所有js文件放在一个文件中。
这是代码。
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<base href="/">
<title>FB4 Messenger</title>
<meta name="viewport" content="width=device-width, user-scalable=xo, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="css/style.css">
</head>
<body ng-app="chatApp">
<div class="loader">
<div class="loader-text">Laden...</div>
<div class="progress">
<div class="progress-bar progress-bar-danger progress-bar-striped active" role="progressbar" style="width: 100%"></div>
</div>
<!--progress-->
</div>
<!--loader-->
<header>
<nav class="navbar navbar-default" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data- toggle="collapse" data-target="#collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<section class="layout">
<div class="branding">
<a href="/">
<img src="images/header/app_fh_logo.png" alt="App logo">
</a>
</div>
<!--branding-->
</section>
<!--layout-->
</div>
<!--navbar-header-->
</div>
<div class="collapse navbar-collapse" id="collapse">
<ul class="nav navbar-nav navbar-right">
<li class="active">
<a href="/">
<span class="glyphicon glyphicon-home"></span>
Startseite
</a>
</li>
<li>
<a href="/profile">
<span class="glyphicon glyphicon-user"></span>
Konto
</a>
</li>
<li>
<a href="/about">
<span class="glyphicon glyphicon-info-sign"></span>
Über
</a>
</li>
</ul>
</div>
<!-- navbar collapse -->
</nav>
</header>
<!--header-->
<!-- ANGULAR DYNAMIC CONTENT -->
<div ng-view></div>
<script src="js/script.js"></script>
</body>
</html>
home.html
<div class="container">
<ul id="messages"></ul>
<div>
<input id="m" ng-model="message" autocomplete="off" />
<button id="send" ng-click="send()">Send</button>
</div>
</div>
about.html
<div class="container">
<div class="card">
<img class="card-img-top" src="../images/header/app_fh_logo.png" alt="Card image cap">
<div class="card-body">
<h3 class="card-title">FB4 Messenger</h3>
<p class="card-text">Version: 0.0.1 </br> Ⓒ </p>
<a href="/" class="btn btn-primary">Startseite</a>
</div>
</div>
</div>
app.js
let $ = jQuery = require("jquery");
require("./bootstrap.min");
require("angular");
require("angular-route");
angular.module("chatApp", ["ngRoute", "appRoutes", "MainCtrl", "ProfileCtrl", "AboutCtrl"]);
$(function() {
$(".loader").fadeOut(1000);
});
appRoutes.js
angular.module("appRoutes", []).config(["$routeProvider", "$locationProvider",
function($routeProvider, $locationProvider) {
$routeProvider
.when("/", {
templateUrl: "views/home.html",
controller: "MainController"
})
.when("/profile", {
templateUrl: "views/profile.html",
//controller: "ProfileController"
})
.when("/about", {
templateUrl: "views/about.html",
//controller: "AboutController"
});
$locationProvider.html5Mode(true);
}
]);
mainCtrl.js
(此处邮件已发送至服务器)
angular.module("MainCtrl", []).controller("MainController", ["$scope",
function ($scope) {
let io = require("socket.io-client");
let socket = io.connect();
$scope.send = function () {
socket.emit("message", $scope.message);
$scope.message = "";
};
$("body").keypress(function (event) {
if (event.keyCode === 13) {
$("#send").click();
}
});
socket.on("message", function (m) {
let $li = $("<li>").text(m);
$("#messages").append($li);
});
}
]);
接收消息的服务器 index.js
const express = require("express");
const http = require("http");
let app = express();
let server = http.createServer(app);
app.use(express.static(__dirname + "/"));
app.get("*", function (req, res){
res.sendFile(__dirname+"/index.html");
});
let io= require("socket.io")(server);
io.on("connection", function (socket) {
socket.on("message", function (m) {
io.emit("message", m);
console.log(m);
});
});
server.listen(3000, function () {
console.log("Server runing");
});
答案 0 :(得分:1)
这是问题所在。
$("body").keypress(function (event) {
if (event.keyCode === 13) {
$("#send").click();
}
});
每次控制器加载时,它都会作为新功能附加到主体上。因此它每次都会触发相同的函数调用。
我建议你可以使用这个
$("body").removeAttr("keypress");
$("body").keypress(function (event) {
if (event.keyCode === 13) {
$("#send").click();
}
});
更好的是,使用ng-click / ng-keyup并提供范围内的功能
// home.html
ng-keyup="$event.keyCode == 13 && vm.sendFn()"
// in controller
vm.sendFn=function(){
... code ...for ..send
}
<强>被修改强> 你能用这种方式改变MainController并尝试。 它可能是因为类似的东西而发生的 - https://github.com/angular-fullstack/generator-angular-fullstack/issues/490
let io = require("socket.io-client");
let socket = io.connect();
socket.on("message", function (m) {
let $li = $("<li>").text(m);
$("#messages").append($li);
});
angular.module("MainCtrl", []).controller("MainController", ["$scope",
function ($scope) {
$scope.send = function () {
socket.emit("message", $scope.message);
$scope.message = "";
};
}
]);