博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Knockout应用开发指南 第九章:高级应用举例
阅读量:6595 次
发布时间:2019-06-24

本文共 8802 字,大约阅读时间需要 29 分钟。

原文:

1   Contacts editor

这个例子和微软为演示jQuery Data Linking Proposal例子提供的例子一样的提供的,我们可以看看Knockout实现是难了还是容易了。

代码量的多少不重要(尽快Knockout 的实现很简洁),重要的看起来是否容易理解且可读。查看HTML源代码,看看如何实现的view model以及绑定的。

 

 

代码: View

View Code

Contacts

代码: View model

View Code
var viewModel = {
contacts: new ko.observableArray([ { firstName: "Danny", lastName: "LaRusso", phones: [ { type: "Mobile", number: "(555) 121-2121" }, { type: "Home", number: "(555) 123-4567"}] }, { firstName: "Sensei", lastName: "Miyagi", phones: [ { type: "Mobile", number: "(555) 444-2222" }, { type: "Home", number: "(555) 999-1212"}] } ]), addContact: function () {
viewModel.contacts.push({ firstName: "", lastName: "", phones: [] }); }, removeContact: function (contact) {
viewModel.contacts.remove(contact); }, addPhone: function (contact) {
contact.phones.push({ type: "", number: "" }); viewModel.contacts.valueHasMutated(); }, removePhone: function (contact, phone) {
ko.utils.arrayRemoveItem(contact.phones, phone); viewModel.contacts.valueHasMutated(); }, save: function () {
viewModel.lastSavedJson(JSON.stringify(viewModel.contacts(), null, 2)); }, lastSavedJson: new ko.observable("") }; ko.applyBindings(viewModel);

 

2   Editable grid

该例是使用“foreach”绑定为数组里的每一项来render到 template上。好处(相对于模板内部使用for循环)是当你添加或者删除item项的时候,Knockout不需要重新render – 只需要render新的item项。就是说UI上其它控件的状态(比如验证状态)不会丢失。

如何一步一步构建这个例子并集成ASP.NET MVC,请。

 

 

代码: View

View Code

You have asked for   gift(s)

Gift name Price

代码: View model

View Code
var viewModel = {
gifts: ko.observableArray([ { name: "Tall Hat", price: "39.95" }, { name: "Long Cloak", price: "120.00" } ]), addGift: function () {
this.gifts.push({ name: "", price: "" }); }, removeGift: function (gift) {
this.gifts.remove(gift); }, save: function (form) {
alert("Could now transmit to server: " + ko.utils.stringifyJson(this.gifts)); // To transmit to server, write this: ko.utils.postJson($("form")[0], this.gifts); } }; ko.applyBindings(viewModel); $("form").validate({ submitHandler: function () { viewModel.save() } });

3   Shopping cart screen

这个例子展示的是依赖监控属性(dependent observable)怎么样链在一起。每个cart对象都有一个dependentObservable对象去计算自己的subtotal,这些又被一个进一步的dependentObservable对象依赖计算总的价格。当改变数据的时候,整个链上的依赖监控属性都会改变,所有相关的UI元素也会被更新。

这个例子也展示了如何创建联动的下拉菜单。

 

代码: View

View Code
Category Product Price Quantity Subtotal

Total value:

代码: View model

View Code
function formatCurrency(value) { return "$" + value.toFixed(2); } var cartLine = function () {
this.category = ko.observable(); this.product = ko.observable(); this.quantity = ko.observable(1); this.subtotal = ko.dependentObservable(function () {
return this.product() ? this.product().price * parseInt("0" + this.quantity(), 10) : 0; } .bind(this)); // Whenever the category changes, reset the product selection this.category.subscribe(function () { this.product(undefined); } .bind(this)); }; var cart = function () {
// Stores an array of lines, and from these, can work out the grandTotal this.lines = ko.observableArray([new cartLine()]); // Put one line in by default this.grandTotal = ko.dependentObservable(function () {
var total = 0; for (var i = 0; i < this.lines().length; i++) total += this.lines()[i].subtotal(); return total; } .bind(this)); // Operations this.addLine = function () { this.lines.push(new cartLine()) }; this.removeLine = function (line) { this.lines.remove(line) }; this.save = function () {
var dataToSave = $.map(this.lines(), function (line) {
return line.product() ? { productName: line.product().name, quantity: line.quantity()} : undefined }); alert("Could now send this to server: " + JSON.stringify(dataToSave)); }; }; var cartViewModel = new cart(); ko.applyBindings(cartViewModel, document.getElementById("cartEditor"));

 

4   Twitter client

这是一个复杂的例子,展示了几乎所有Knockout特性来构建一个富客户端。

用户数据存在一个JavaScript模型里,通过模板来展示。就是说我们可以通过清理用户列表里的数据来达到隐藏用户信息的目的,而不需要手动去隐藏DOM元素。

按钮将根据他们是否可操作来自动变成enabled或disabled状态。例如,有一个叫hasUnsavedChanges的依赖监控属性(dependentObservable)控制这“Save”按钮的enabled状态。

可以非常方便地从外部JSON服务获取数据,并集成到view model里,然后显示在页面上。

 

代码: View

View Code
Loading...

Currently viewing   user(s):

代码: View model

View Code
// The view model holds all the state we're working with. It also has methods that can edit it, and it uses // dependentObservables to compute more state in terms of the underlying data // -- // The view (i.e., the HTML UI) binds to this using data-bind attributes, so it always stays up-to-date with // the view model, even though the view model does not know or care about any view that binds to it var viewModel = {
savedLists: ko.observableArray([ { name: "Celebrities", userNames: ['JohnCleese', 'MCHammer', 'StephenFry', 'algore', 'StevenSanderson'] }, { name: "Microsoft people", userNames: ['BillGates', 'shanselman', 'haacked', 'ScottGu'] }, { name: "Tech pundits", userNames: ['Scobleizer', 'LeoLaporte', 'techcrunch', 'BoingBoing', 'timoreilly', 'codinghorror'] } ]), editingList: {
name: ko.observable("Tech pundits"), userNames: ko.observableArray() }, userNameToAdd: ko.observable(""), currentTweets: ko.observableArray([]) }; viewModel.findSavedList = function (name) {
var lists = this.savedLists(); for (var i = 0; i < lists.length; i++) if (lists[i].name === name) return lists[i]; }; // Methods viewModel.addUser = function () {
if (this.userNameToAdd() && this.userNameToAddIsValid()) {
this.editingList.userNames.push(this.userNameToAdd()); this.userNameToAdd(""); } } viewModel.saveChanges = function () {
var saveAs = prompt("Save as", this.editingList.name()); if (saveAs) {
var dataToSave = this.editingList.userNames().slice(0); var existingSavedList = this.findSavedList(saveAs); if (existingSavedList) existingSavedList.userNames = dataToSave; // Overwrite existing list else this.savedLists.push({ name: saveAs, userNames: dataToSave }); // Add new list this.editingList.name(saveAs); } } viewModel.deleteList = function () {
var nameToDelete = this.editingList.name(); var savedListsExceptOneToDelete = $.grep(this.savedLists(), function (list) { return list.name != nameToDelete }); this.editingList.name(savedListsExceptOneToDelete.length == 0 ? null : savedListsExceptOneToDelete[0].name); this.savedLists(savedListsExceptOneToDelete); }; ko.dependentObservable(function () {
// Observe viewModel.editingList.name(), so when it changes (i.e., user selects a different list) we know to copy the saved list into the editing list var savedList = viewModel.findSavedList(viewModel.editingList.name()); if (savedList) {
var userNamesCopy = savedList.userNames.slice(0); viewModel.editingList.userNames(userNamesCopy); } else viewModel.editingList.userNames([]); }); viewModel.hasUnsavedChanges = ko.dependentObservable(function () {
if (!this.editingList.name()) return this.editingList.userNames().length > 0; var savedData = this.findSavedList(this.editingList.name()).userNames; var editingData = this.editingList.userNames(); return savedData.join("|") != editingData.join("|"); }, viewModel); viewModel.userNameToAddIsValid = ko.dependentObservable(function () {
return (this.userNameToAdd() == "") || (this.userNameToAdd().match(/^\s*[a-zA-Z0-9_]{1,15}\s*$/) != null); }, viewModel); // The active user tweets are (asynchronously) computed from editingList.userNames ko.dependentObservable(function () {
twitterApi.getTweetsForUsers(this.editingList.userNames(), function (data) { viewModel.currentTweets(data) }) }, viewModel); ko.applyBindings(viewModel); // Using jQuery for Ajax loading indicator - nothing to do with Knockout $(".loadingIndicator").ajaxStart(function () { $(this).fadeIn(); }) .ajaxComplete(function () { $(this).fadeOut(); });

转载地址:http://kijio.baihongyu.com/

你可能感兴趣的文章
我的友情链接
查看>>
修改3389远程默认登录端口
查看>>
PKI课程练习
查看>>
xp下无线网卡做AP
查看>>
Perl中的REPL
查看>>
可适配图片的ExpandableListView
查看>>
js实现类似php中strtotime函数和timetostr的日期转换/互换功能
查看>>
NFS配置及使用
查看>>
Lync尝试之启动Lync客户端出现进度条
查看>>
开始→运行→命令集锦
查看>>
SQL语句获取所有数据库名、表名、字段名、表字段长度
查看>>
我的友情链接
查看>>
Installation Oracle11gR2 RAC---修改在线日志
查看>>
mysql事务
查看>>
我的友情链接
查看>>
Android模拟器使用SD卡
查看>>
Java多线程实现同步——wait()和notify()实现
查看>>
Spark 性能相关参数配置详解-任务调度篇
查看>>
命令行查询memcache
查看>>
【CentOS 7笔记21】,磁盘挂载#171103
查看>>