Javascript函数执行两次,Meteor js

标签 javascript meteor iron-router

这是一个简单的水平幸运轮盘脚本,使用光滑的 slider 创建。问题:函数 rollout() 执行了两次(所有的辅助函数也是如此)因为模板渲染了两次。我正在使用 iron:router 进行路由,代码:

Router.configure({
  loadingTemplate: "loading",
  layoutTemplate: "layout"
});
Router.map(function() {
  this.route("hello", {
    path: "/",
    waitOn: function() {
      return Meteor.subscribe("games");
    }
  });
});

你好.js:

Session.setDefault('currentSlide', 0);
    Template.hello.events({
      'click .create': function(e) {
        e.preventDefault();
        var ins = {
          gameStartTime: new Date(),
          finished: false
        }
        Games.insert({
          gameStartTime: new Date(),
          finished: "false"
        });
        Session.set("gameStatus", "waiting");
      }
    })
    Template.hello.helpers({
      currentSlide: function() {
        var value = Session.get('currentSlide');
        if (value === 25) {
          return 0;
        }
        return value;
      },
      games: function() {
        var game = Games.find();
        return game;
      },
      gameHandler: function() {
        var game = Games.findOne();
        var gameStatus = Session.get("gameStatus");
        if (game && game.finished === "false" && gameStatus === "waiting") {
          Games.update({_id: game._id}, {
            $set: {running: true}
          });

        } else if (gameStatus === "finished") {

          Meteor.call('updateGame', game._id); //remove item from collection after game over; Error here: TypeError: Cannot read property '_id' of undefined; 
          console.log('game finished');
        }
        if (game && game.running === true) {
          //Set Session variable and launch roulette
          Session.set("gameStatus", "running");
          rollout(game._id);
        }
      }
    });
    var rollout = function(gameid) {
      Session.set("gameStatus", "running");
      //make div's visible. They are have display:none by default.
      document.getElementById("roulette").style.display = "block";
      document.getElementById("result").style.display = "block";
      document.getElementById("wrapper").style.display = "none";
      var speed = 500; //default slider speed
      Session.setDefault('speed', speed);
      var r = $('#roulette').slick({
        centerMode: true,
        slidesToShow: 7,
        slidesToScroll: 1,
        autoplay: true,
        autoplaySpeed: 0,
        speed: speed,
        draggable: false,
        pauseOnHover: false,
        cssEase:'linear'
      });
      var maximum = 14;
      var minimum = 0;
      var randomnumber = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
      var winResult = randomnumber;
      var speed = 80;
      var currentSlide = Session.get('currentSlide');
      function roll(callback) {
        Session.set('currentSlide', r.slickCurrentSlide());
        if (speed < 800) {
          speed += 20;
          r.slickSetOption("speed", speed, false);
          setTimeout(function() {
            roll(callback);
          }, 500);
        } else if (speed >= 600 && speed < 1300) {
          speed += 40;
          r.slickSetOption("speed", speed, false);
          setTimeout(function() {
            roll(callback);
          }, 300);
        } else if (speed >= 1300 && speed < 20000) {
          setTimeout(function() {
            speed += 3;
            r.slickSetOption('speed', speed, false);
            if (Session.get('currentSlide') === winResult) {
              r.slickPause();
              setTimeout(function() {
                //hide roulette div's
                document.getElementById("roulette").style.display = "none";
                document.getElementById("result").style.display = "none";
                document.getElementById("wrapper").style.display = "block";
                r.unslick();

                Session.set('currentSlide', 0);
                Session.set("gameStatus", "finished");
                callback(true);
                return
              }, 10000);
            } else {
              roll(callback);
            }
          }, 30)
        }  else {
          callback(true);
        }
      }
      roll(function(callback) {
        Meteor.call('updateGame', gameid); //remove item from collection
        Session.set("gameStatus", "finished");
      });
    }

在模板中,我使用 sacha:spin 包的微调器,它工作正常。

最佳答案

gameHandler 函数不应该在你的模板助手中,它只是为了向模板提供信息。相反,该逻辑需要移至 autorun function。 .此自动运行语句将在其中的响应式(Reactive)数据源发生更改时重新运行。

例如:

Template.hello.onCreated(function() {
    this.autorun(function() {
        var game = Games.findOne();
        var gameStatus = Session.get("gameStatus");
        // ...etc
    });
}

关于Javascript函数执行两次,Meteor js,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34662391/

相关文章:

javascript - 使用 AJAX 的数据表,求和并添加总页脚

javascript - 当在 Meteor 中呈现不同的模板时如何删除类

javascript - 如何从一系列捐赠中返回每个独特捐赠类别的总计?

javascript - 如何消除 Meteor 模板闪烁

inheritance - IronRouter 在路由 Controller 上扩展数据选项

javascript - cryptojs 和 golang 给出不同的 sha3 哈希值

javascript - Node (Express) 上的套接字 IO 的 cURL 请求

javascript - 如何更新或操作从父级加载到 iframe 中的内容?

javascript - mongodb:从数组中删除一个对象

javascript - 我在对象上遇到错误 - Meteorjs Iron-router Internet Explorer 8 (ie8)