Backbone.js - 以编程方式加载视图

时间:2011-08-23 13:38:34

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

所以我不完全确定我正在采用Backbone.js的正确方法以及我想要做的事情,但让我试着解释一下。

我正在创造一个移动“游戏”。游戏非常简单,你连接到Facebook并“登录”,选择一个级别[Easy | Medium | Hard]并开始游戏。

游戏由6个任务组成,用于使用地理位置查找特定区域(您应该距离该位置15米范围内完成任务)。

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

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

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

每个Quest共享相同的View,我想最终通过Ajax填充Quest Models。

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

我正在使用jQuery&带有下划线和Backbone的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>

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

谢谢!

2 个答案:

答案 0 :(得分:0)

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

只有几点:

  • 你应该用QuestsCollection.length替换6吗?这样你就可以动态添加任务并适当调整

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

  • 要添加任务,它应该像向系列中添加新Quest一样直截了当:QuestsCollection.add({})

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

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

答案 1 :(得分:0)

我此刻也在考虑这个问题,所以没有明确的答案。

但是,请看一下这个帖子:

http://pinoytech.org/question/7172294/backbone-js-and-jquerymobile-routing-without-hack-or-other-router

你实际上想要自己调用JQM的changePage。下周还有一篇文章你会觉得有用:

http://msdn.microsoft.com/en-us/scriptjunkie/hh377172.aspx