javascript - Backbone.js - 以编程方式加载 View

标签 javascript jquery-mobile backbone.js underscore.js

所以我不完全确定我对 Backbone.js 采取了正确的方法以及我正在尝试做的事情,但让我尝试解释一下。

我正在创建一款移动“游戏”。游戏非常简单,您连接到 Facebook 并“登录”,选择一个级别 [简单|中|困难],然后开始游戏。

游戏包含 6 个使用地理定位寻找特定区域的任务(您应该在距离该位置 15 米的范围内才能完成任务)。

您还会获得一些生命线,以帮助您找到位置,就像“谁想成为百万富翁”的风格。

我离题了。我正在使用 Backbone.js,但这是我第一次尝试 Javascript MVC,我有点不确定应该如何使用它。

当玩家告诉应用程序他们认为他们在该位置时,我希望能够在检查位置后将玩家移动到下一个任务(前提是他们不在第六个也是最后一个任务中)并简单地更新他们的分数。

每个任务共享相同的 View ,我希望最终通过 Ajax 填充任务模型。

我最大的问题是弄清楚如何优雅地从任务 1 转到任务 2。

我正在使用带有下划线和 Backbone 的 jQuery 和 jQueryMobile。

这是迄今为止我的代码:

$(document).bind("mobileinit", function() {
    $.mobile.hashListeningEnabled = false;
    $.mobile.ajaxEnabled = false;

    var PROGRESS = 1;

    var Quest = Backbone.Model.extend({
        defaults: {
            id: 0,
            message: '',
            points: 0,
            latitude: '0',
            longitude: '0',
            clues: {}
        },
        initialize: function(){

        },
        addPoints: function(points) {
            this.set({points: this.get('points') + points});
        },
        takePoints: function(points) {
            this.set({points: this.get('points') - points});
        }
    });


    var QuestsCollection = Backbone.Collection.extend({
        model: Quest,
        comparator: function(quest) {
            return quest.get('id');
        },
        getFinalScore: function() {
            var points = this.pluck('points');
            var total = 0;
            $.each(points, function(k, v) {
                total += v;
            });
            return total;
        }
    });

    var QuestView = Backbone.View.extend({
        el: '#play',
        tagName: 'div',
        className: 'quest',
        template: _.template($('#play-tpl').html()),
        model: Quest,
        quest: {},
        questNumber: 1,
        location: {latitude: 0, longitude: 0},
        events: {
            'click .amIWarm' : 'checkGeoWarmth',
            'click .imThere' : 'complete',
            'click .skipQuest' : 'skip'
    },
        initialize: function() {
            this.questNumber = this.options.questNumber;
            this.quest = this.options.quest;
        },
        checkGeoWarmth: function(event) {
            console.log(event);
            console.log('checkGeoWarmth');
        },
        complete: function(event) {
            console.log('Check that the user is located within 30 metres of the target!');
            console.log('If the user is actually at the location, move them on to the next quest and save their points.');
            this.questNumber += 1;
            PROGRESS += 1;
            console.log(PROGRESS);

            if (PROGRESS >= 6) {
                console.log('Game Over!');
            }
    },
    skip: function(event) {
            console.log('Set points to 0');
            console.log('Move on to the next quest.');
            this.questNumber += 1;

            if (this.questNumber >= 6) {
                console.log('Game Over!');
            }
        },
    render: function() {
            $('.page').hide();
            $(this.el).show();
            console.log(this.quest);
            $(this.el).html(this.template({quest: this.quest}));
    }
    });

    var Game = Backbone.Router.extend({
        routes: {
            "": "welcome",
            "/play/:quest": "play"
        },
        welcome: function() {
            var SplashPage = new SplashView;
            SplashPage.render();
        },
        selectLevel: function() {
            console.log('Select Level');
        },
        play: function(quest) {
            var thisQuest = Quests.get(quest);
            var QuestPage = new QuestView({quest: thisQuest});
            //console.log(QuestPage);
            QuestPage.render();
        },
        gameOver: function() {
            var score = Quests.getFinalScore();
            // Score
            console.log('Your Score is ' + score);
            // Save Score
            console.log('Send Ajax Request to [/score/save] with [{player_id: 1, facebook_id: 1234567890, score: 440}]')
            // Share On Facebook
            console.log('Share your score on Facebook?');
            // Tweet?
            console.log('Share your score on Twitter?');
        },
        leaderboard: function() {
            // Model: Score
            // Collection: Scores
            // View: Score
        }
    });
    var game = new Game;
    Backbone.history.start();
});

我的 HTML 如下:

<!DOCTYPE html>
<html>
<head>
<title>GeoQuest</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1; user-scalable=1;" />
<link type="text/css" rel="stylesheet" href="css/jquery.mobile.css" />
<link rel="stylesheet" type="text/css" href="css/geoquest.css" />
</head>
<body>
    <div id="splash" class="page" data-role="page">
        <script type="text/html" id="splash-tpl">
        <a href="#/play/1">Play</a>
        <button class="connect">Connect</button>
        <button class="disconnect">Disconnect</button>
        </script>
    </div>
    <div id="select-level" class="page" data-role="page">
    </div>
    <div id="play" class="page" data-role="page">
        <script type="text/html" id="play-tpl">
        <h1>Quest <%= quest.id %></h1>
        <div class="quest-message">
            <%= quest.message %>
        </div>
        <button class="skipQuest" data-role="button">Skip Quest</button>
        <button href="/play/2" class="imThere" data-role="button">I'm There</button>
        <button class="amIWarm" data-role="button">Am I Warm</button>
        </script>
    </div>
<div id="fb-root"></div>
<script type="text/javascript">
window.fbAsyncInit = function() {
    FB.init({appId: '140750459345068', status: true, cookie: true, xfbml: true});
    window.FB = FB;
};
(function() {
    var e = document.createElement('script'); e.async = true;
    e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
    document.getElementById('fb-root').appendChild(e);
}());
</script>
<script type="text/javascript" src="js/jquery.js"> </script>
<script type="text/javascript" src="js/underscore.js"> </script>
<script type="text/javascript" src="js/backbone.js"> </script>
<script type="text/javascript" src="js/json2.js"> </script>
<script type="text/javascript" src="js/geoquest.js"> </script>
<script type="text/javascript" src="js/jquery.mobile.js"> </script>
</body>
</html>

非常感谢任何帮助或建议。

谢谢!

最佳答案

我也一直在玩弄backbone,到目前为止我很喜欢它。

简单说几点:

  • 是否应该将 6 替换为 QuestsCollection.length?这样您就可以动态添加任务并对其进行适当调整

  • 在你的 QuestView 上,当你完成任务时,如果游戏没有结束,则让它调用 this.render(),并且应该显示下一个任务 创建一个新的 QuestView({下一个任务模型})并调用 .render() 函数或重定向到/play/quest#?

  • 要添加任务,应该像将新任务添加到集合中一样简单:QuestsCollection.add({})

这是我的示例程序/游戏,如果您想查看的话。它很大程度上基于官方backbone.js站点上的todo程序:http://rickcoder.com/bbtest/ (使用一些 html 5 本地存储功能,因此它仅适用于较新的浏览器)

主干相关代码在这里http://rickcoder.com/bbtest/bbtest.js

关于javascript - Backbone.js - 以编程方式加载 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7161874/

相关文章:

javascript - 在 javascript 中使用 sha1 对文本进行哈希处理

jquery-mobile - 如何关闭弹出对话框页面并从代码中打开另一个?

javascript - 当所有 child 都被解雇时移除容器

javascript - 调用函数用正则表达式替换某些子字符串的问题

javascript - 使用 javascript 单击元素

javascript - 响应式 jQuery Mobile 标题按钮

javascript - 在获取/保存后更新 Backbone 子模型

javascript - 主干/Marionette 路由 - 缺乏深度

JavaScript promise : UnhandledPromiseRejectionWarning

javascript - 我怎样才能让 jquery mobile "pagebeforeshow"事件每次都触发,而不仅仅是刷新