0

我正在开发一个针对移动用户的单页网站(最终将移植到 Phonegap)。我已将我的屏幕分解为“卡片”,这些卡片基本上只是<div>我根据需要显示/初始化/隐藏的内容。

目前,我无法决定使用正确的结构来实现将这些面板链接在一起成为一个连贯的应用程序。我目前的实现是这样的(目前使用我熟悉的 Knockout):

//Javascript
var LoginCard = function() {
    this.goToRegister = function() { 
        // IF registerCard is not initialized
        // THEN ko.applyBindings(new RegisterCard(), document.getElementById('registerCard'));
        // ELSE $('#registerCard').show();
    };
    this.doLogin = function() { /* Goes to home card after login */ };
}
var RegisterCard = function() {
    this.goToLogin = function() { /* Goes back to login card */ };
    this.doRegister = function() { /* Goes to login card after reg */ };
}
ko.applyBindings(new LoginCard(), document.getElementById('loginCard'));

//HTML
<div id="loginCard">
    <button data-bind="click: goToRegister" id="btnReg">Register Account</button>
    <button data-bind="click: doLogin" id="btnLogin">Login</button>
</div>
<div id="registerCard">
    <button data-bind="click: goToLogin" id="btnBackToLogin">Back To Login</button>
    <button data-bind="click: doRegister" id="btnDoReg">Submit Registration</button>
</div>

如您所见,链接发生在视图模型本身内,因此不同的视图模型(例如 loginCard、registerCard、homeCard)彼此紧密耦合。

一个更“低级”的替代方案是使用 jQuery 绑定按钮事件,这样每张卡就不必知道其他卡的详细信息:

//But this means I have to specify a ton of unique IDs for all the elements in the page.
$('#btnReg').click(function() { /* Initialize and go to registerCard. */ });

我还考虑过使用 hash-routing/pushState,所以当点击事件仍在每个视图模型中时,它只需要知道要访问的 URL 吗?就像是:

var LoginCard = function() {
    this.goToRegister = function() { 
        window.location.hash = 'register';
        //or history.pushState('state', '', 'register';
    };
}

这是我第一次尝试创建单页应用程序,所以我对设计选择感到非常困惑。哪一个会更好,或者任何人都可以提出标准的方法来解决这个问题?

4

1 回答 1

1

我建议您为路由创建另一个对象,该对象依赖于 SammyJS 或 CrossroadsJS 等路由库。

请参考我的爱好项目MyStory.Spa,它也是单页应用程序样式的 web(不适用于移动应用程序),它使用 SammyJS 进行浏览器级路由。在 MyStory.Spa 架构中,webapp/app/infra/router.js 负责路由,有关路由、视图、视图模型的详细信息在 /webapp/app/infra/routing.table.js 中。

这样就可以解耦View、ViewModel、Model、Data Service、Routing等等。

于 2012-11-28T08:45:05.797 回答