knockoutjs 单页引用 客户端重定向(location.hash history.pushState)

大部分现代的,相应的,迷人的Web应用已经超越经典的Ajax,变成单页引用(single page applications:)。用户能象使用本地应用一样,在一个界面内完成各种操作,一个很著名的例子就是:GMail。

这些[color=red]单页引用使用hash-based url 或者 pushState 导航来支持 浏览器的回退、前进、书签操作[/color]。(location.hash就是#锚点,一般用在Web页面内部的片段之间进行导航!)

data-bind="text: $data": $data表示引用foreach循环中的数组数据

data-bind="with: chosenFolderData": with表示后面的变量chosenFolderData不是null时,才使用绑定的相关控件。with内部的所有控件绑定变量时,引用就不需要再加chosenFolderData.前缀了,直接使用mails就可以

chosenFolderId, chosenFolderData , chosenMailData 都是被观察对象,在相关操作时给这些变量设置, 然后一些绑定到这些变量的UI会被自动更新。chosenFolderId[color=red]是被观察者,所有取值、设置都是通过方法的形式做的[/color]

client-side navigation客户端重导航,使用hash-based url 或者 pushState技术。[url=http://sammyjs.org/]Sammy [/url]就是使用hash-based url。

Sammy js client-side navigation的基本技术是采用一层额外的indirection客户端内部定向。没有使用之前,goToFolder 和goToMail 方法都是直接调用Ajax请求然后更新viewmodel 的状态。使用后,goToFolder 和goToMail 方法仅仅触发client-side navigation客户端导航,然后Sammy 包会捕获到客户端导航操作再发出相应的Ajax请求后再更新viewmodel状态。indirection客户端内部定向也就意味着[color=red]如果用户点击浏览器上面的回退、前进按钮,Sammy会捕获到这些请求,然后viewmodel 会被正常更新[/color]

location是javascript里边管理地址栏的内置对象,比如location.href就管理页面的url,用location.href=url就可以直接将页面重定向url。一个完整的URL地址的格式为:协议://主机:端口[color=red]/路径名称#hash标识?搜索条件[/color],
而[color=red]location.hash则可以用来获取或设置页面的标签值。比如http://domain/#admin?a=1的location.hash="#admin?a=1"。[/color]
[color=blue]onhashchange在#后面的url发生变化时触发 [/color]


<!-- Todo: Create UI -->
<script src="/scripts/lib/sammy.js" type="text/javascript"></script>

<!-- Folders -->
<ul class="folders" data-bind="foreach: folders">
<li data-bind="text: $data,
css: { selected: $data == $root.chosenFolderId() },
click: $root.goToFolder"></li>
</ul>

<!-- Mails grid -->
<table class="mails" data-bind="with: chosenFolderData">
<thead><tr><th>From</th><th>To</th><th>Subject</th><th>Date</th></tr></thead>
<tbody data-bind="foreach: mails">
<tr data-bind="click: $root.goToMail">
<td data-bind="text: from"></td>
<td data-bind="text: to"></td>
<td data-bind="text: subject"></td>
<td data-bind="text: date"></td>
</tr>
</tbody>
</table>


<!-- Chosen mail -->
<div class="viewMail" data-bind="with: chosenMailData">
<div class="mailInfo">
<h1 data-bind="text: subject"></h1>
<p><label>From</label>: <span data-bind="text: from"></span></p>
<p><label>To</label>: <span data-bind="text: to"></span></p>
<p><label>Date</label>: <span data-bind="text: date"></span></p>
</div>
<p class="message" data-bind="html: messageContent" />
</div>


function WebmailViewModel() {
// Data
var self = this;
self.folders = ['Inbox', 'Archive', 'Sent', 'Spam'];
self.chosenFolderId = ko.observable();
self.chosenFolderData = ko.observable();
self.chosenMailData = ko.observable();

// Behaviours
//self.goToFolder = function(folder) {
// self.chosenFolderId(folder);
// self.chosenMailData(null); // Stop showing a mail
// $.get('/mail', { folder: folder }, self.chosenFolderData);
//};
//self.goToMail = function(mail) {
// self.chosenFolderId(mail.folder);
// self.chosenFolderData(null); // Stop showing a folder
// $.get("/mail", { mailId: mail.id }, self.chosenMailData);
//};
self.goToFolder = function(folder) { location.hash = folder };
self.goToMail = function(mail) { location.hash = mail.folder + '/' + mail.id };

// Show inbox by default
// self.goToFolder('Inbox');

// Client-side routes
Sammy(function() {
this.get('#:folder', function() {
self.chosenFolderId(this.params.folder);
self.chosenMailData(null);
$.get("/mail", { folder: this.params.folder }, self.chosenFolderData);
});

this.get('#:folder/:mailId', function() {
self.chosenFolderId(this.params.folder);
self.chosenFolderData(null);
$.get("/mail", { mailId: this.params.mailId }, self.chosenMailData);
});

this.get('', function() { this.app.runRoute('get', '#Inbox') });
}).run();
};

ko.applyBindings(new WebmailViewModel());
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值