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

发布于 2024-12-01 06:08:24 字数 6913 浏览 2 评论 0原文

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

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

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

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

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

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

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

我最大的问题是弄清楚如何优雅地从任务 1 转到任务 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>

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

谢谢!

so I'm not entirely sure I'm taking the correct approach with Backbone.js and what I'm trying to do but let me try to explain nonetheless.

I'm creating a mobile "game". The game is pretty simple, you connect to Facebook and "log in", select a level [Easy|Medium|Hard] and start the game.

The game consists of 6 Quests to find a particular area using geolocation (You should be within 15 metres to of the location to finish the quest).

You also get a few lifelines in order to help you find the location, in the style of "Who wants to be a Millionaire".

I digress. I'm using Backbone.js but its my first stab at Javascript MVC and I'm a little unsure of how I'm supposed to be using it.

When a player tells the app that they think the are at the location, I would like to be able to, after checking the location, move the player to the next Quest (provided they are not on the 6th and last quest) and simply update their score.

Each Quest shares the same View and I would like to populate the Quest Models via Ajax eventually.

My biggest problem is figuring out how to get from Quest 1 to Quest 2 gracefully.

I'm using jQuery & jQueryMobile with underscore and Backbone.

Here is my code so far:

$(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();
});

My HTML is as follows:

<!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>

Any help or advice is well appreciated.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

羁〃客ぐ 2024-12-08 06:08:24

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

只是几点:

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

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

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

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

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

I've been playing around with backbone also, and loving it so far.

Just a couple of points:

  • Should you replace 6 with QuestsCollection.length? That way you can add quests dynamically and have it adjust appropriately

  • On your QuestView, when you complete the quest, have it call this.render() if it is not game over, and the next quest should display create a new QuestView({next quest model}) and call the .render() function or redirect to /play/quest#?

  • To add quests, it should be as straight forward as adding a new Quest into the collection: QuestsCollection.add({})

Here's my sample program/game, if you want to check it out. It is heavily based on the todo program on the official backbone.js site: http://rickcoder.com/bbtest/ (uses some html 5 local storage capabilities, so it only works on newer browsers)

The backbone related code is here http://rickcoder.com/bbtest/bbtest.js

绝不放开 2024-12-08 06:08:24

我现在也在研究这个问题,所以没有明确的答案。

但是,看看这个线程:

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

I'mm looking into this as well at the moment so don't have a definitive answer.

However, have a look at this thread:

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

You effectively want to call JQM's changePage yourself. There is also an article out next week you'll find useful:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文