Angular多次运行控制器

时间:2017-11-09 15:44:16

标签: javascript angularjs node.js

我目前正在开发一个聊天网络应用。这应该被实现为单页面应用程序。为此,我使用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> &#9400; </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");
});

1 个答案:

答案 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 = "";
        };

    }
]);