了解淘汰赛
KnockoutJS是基于Model-View-ViewModel模式的优雅JavaScript库,可帮助我们轻松创建丰富的用户界面。 如果您开发的应用程序具有可在基础数据模型发生更改时动态更新的部分,那么Knockout确实可以为您提供帮助。 Knockout中的两种数据绑定和模板功能使实现动态视图的过程变得轻而易举。 本教程将使您开始使用Knockout,并向您展示如何在自己的项目中使用它。
安装淘汰赛
安装Knockout只需在HTML页面中包含一个小的JavaScript文件即可。 前往Knockout网站并下载生产版本。 或者,您可以包括CDN的淘汰赛。 只需将以下标记放在HTML文档中即可。
MVVM模式
为了有效地使用Knockout,您必须首先了解MVVM模式是什么。 如果您已经了解了MVVM模式,则可以跳到下一部分。
模型: MVVM中的M代表模型,通常是应用程序保留的业务数据。 在大多数情况下,您最初将通过Ajax调用从服务器读取此数据并将其显示在UI上。 例如,如果要从服务器检索笔记列表,则可以向服务器发出Ajax GET请求。
视图:在淘汰赛中,视图只是显示ViewModel的HTML页面(我们将介绍)。 只要这些ViewModel发生更改,链接到ViewModel的视图的特定部分也会更改。
ViewModel:简单来说,ViewModel是由View呈现的模型。 它是数据及其上支持的操作的纯代码表示。 ViewModel通常不持久保存,并保存用户正在使用的未保存的更改。 如果要以后保存更改,则可以将此数据发布回服务器。 在淘汰赛中,ViewModels由POJO(普通的旧JavaScript对象)实现。 例如,如果要显示待办事项列表,则ViewModel可能会保存此类便笺对象的列表,并公开几个用于修改/添加便笺的函数。
入门
作为学习Knockout的第一步,让我们研究一下ViewModels和数据绑定。 以下代码段创建了一个简单的ViewModel:
function NameViewModel() {this.name = 'John Doe';
} 或者,可以将ViewModel编写为对象,如下所示。
var nameViewModel = {name: 'John Doe'
} 现在,在HTML中,您只需要编写以下声明性绑定即可与ViewModel的name属性连接。
Hello, 此代码段仅将UI与ViewModel的name属性连接。 在这里, name的值是将innerHTML ed插入span标记中。 现在,作为最后一步,我们需要告诉Knockout name属性属于哪个ViewModel。 为此,只需添加以下代码。
ko.applyBindings(new NameViewModel()); 这会导致淘汰赛执行数据绑定。 结果,在HTML中,我们在span元素内看到name的值。
注意:在复杂的应用程序中,您可能有多个ViewModel,而不仅仅是一个。 在那种情况下,您可以通过将第二个参数传递给ko.applyBindings()来将特定的ViewModel绑定到UI的特定部分。 下面是一个示例。
ko.applyBindings(new ContactViewModel(), document.getElementById('contacts-area'));
ko.applyBindings(new NoteViewModel(), document.getElementById('notes-area')); 最后要注意的一点是,在文档准备就绪之前,不应调用ko.applyBindings() 。 如果使用的是jQuery,则将调用包装在$(document).ready() 。 在VanillaJS中 ,您可以使用DOMContentLoaded事件处理程序。
与Observable的双向绑定
我们刚刚学习了如何将模型属性绑定到UI。 但是,我们可以走得更远,使它变得动态。 使用可观察对象,您可以将属性绑定到UI上,这有另一个好处-每当ViewModel属性更改时,UI就会自动更新。 此外,我们可以使用Knockout的声明性绑定功能,以便只要UI中的值(例如,输入字段值)发生更改,ViewModel属性也将更新。 这样可以使ViewModel和View保持同步。
要根据属性值更新视图,需要使该属性可观察。 这很简单。 只需修改我们之前的代码,如下所示:
function NameViewModel() {this.name = ko.observable(''); //initially empty
} 现在,只要name属性更改,我们的视图就会更新。 现在,让我们在HTML中添加一个输入字段并将其绑定到name以便每当用户在其中键入内容时,属性都会更改,并且我们会在span标记中看到更新的值。
Hello, 在这里,我们利用了Knockout的声明性绑定语法。 在data-bind属性中,该value指示我们要绑定到的属性。 第二个参数valueUpdate指定何时更新ViewModel属性。 由于我们将其设置为'input' ,因此只要输入字段值更改,ViewModel中的属性就会更新。 要查看此功能的实际效果,请看一下该插头。
每当任何可观察的值更改时,您还可以获取通知。 以下示例显示了如何使用subscribe()函数完成此操作。
function NameViewModel() {this.name = ko.observable('');this.name.subscribe(function(newVal) {console.log(newVal); //logs whenever the value changes});
} 使用计算的可观察物
有时,您可能想使用其派生属性值取决于一个或多个其他属性。 如果要在视图中显示此派生属性,则逻辑上每当它依赖于更改时就对其进行更新是合乎逻辑的。 为此,我们需要一个可计算的可观察对象,其创建方式如下:
function ContactViewModel() {this.phone = ko.observable();this.email = ko.observable();this.contactInfo = ko.computed(function() {return this.phone() + ", " + this.email();}, this);
} 现在,在视图中,我们可以使用以下HTML绑定计算的可观察对象。
Contact Information: 通过查看传递给ko.compute()的回调(或评估函数ko.compute() ,Knockout知道计算出的可观察对象所依赖的可观察对象。 每当它们中的任何一个发生变化时,您的Evaluator函数都会被自动调用。
ko.compute()的第二个参数是应在评估函数内用作this对象的对象。 值得指出的是,您可以使用闭包实现相同的功能,如下所示。
function ContactViewModel() {var self = this;self.phone = ko.observable();self.email = ko.observable();self.contactInfo = ko.computed(function() {return self.phone() + ", " + self.email();});
} 最后要注意的是,当使属性可观察时,您不应再直接在代码中访问它们。 相反,我们需要像函数那样调用它们。 这就是在上一个示例中使用函数调用检索phone和email的值的原因。 要设置可观察值,只需将新值作为函数参数传递(即self.phone(4657324573) )。
可观察阵列
每当我们要检测单个ViewModel属性中的更改时,可观察的方法就是可行的方法。 但是,在许多情况下,我们有兴趣了解对象集合是否已更改。 在这种情况下,我们可以使用通过以下代码创建的可观察数组。
function NotesViewModel() {this.notes = ko.observableArray();
} 创建可观察数组之后,通常将遍历所有项并将其显示在UI上。 每当您将新项目添加到集合中或将其删除时,视图都会自动更新。
您还可以像这样将初始值传递给可观察数组:
this.notes = ko.observableArray(['one', 'two', 'three']); 您还可以执行各种数组操作,例如pop() , push() , shift() , unshift() , reverse() , sort() , splice()等。很好,不是吗?
一个简单的淘汰赛应用程序
在本节中,我们将创建一个带有简单UI的Knockout应用程序,用于管理手机数据。 添加新手机后,详细信息将显示在表格中。 用户还可以从表中删除项目。 看看展示最终结果的演示 !
在继续之前,请确保同时安装了Knockout和Knockout映射插件。 稍后我将讨论映射插件。 现在,只需在Knockout库之后包含以下内容即可:
步骤1
假设每个手机将具有三个属性: name , os和price 。 我们需要创建一个ViewModel,并添加一些示例电话详细信息:
function PhonesViewModel() {var self = this;self.phones = ko.observableArray([{name: 'Sony Xperia Z1',os: 'Android',price: 599}, {name: 'Apple iPhone 5S',os: 'iOS',price: 199}, {name: 'Google Nexus 5',os: 'Android',price: 299}]);
} 如您所见,我们创建了一个可观察的数组,其中包含手机详细信息。 我们将在视图上遍历这些数组元素。
第2步
创建一个对象来保存在视图中输入的当前电话详细信息。 我们需要将以下代码添加到我们的ViewModel中。
self.currentPhone = ko.mapping.fromJS({name: '',os: '',price: ''
}); currentPhone对象保存在UI上输入的电话详细信息。 我们将属性name , os和price绑定到HTML上的输入字段。 添加电话详细信息后,我们也希望清除这些字段。 为了清除这些字段,我们需要使这些属性可观察,然后在添加电话的功能中清除它们。 Knockout映射插件中的ko.mapping.fromJS()函数自动使对象属性可观察,因此我们不必为每个属性编写ko.observable() 。
第三步
接下来,我们要提供一种将新手机添加到列表中的方法。 只需将以下函数添加到我们的ViewModel中即可。
self.addPhone = function() {self.phones.push(ko.mapping.toJS(self.currentPhone));self.currentPhone.name('');self.currentPhone.os('');self.currentPhone.price('');
}; ko.mapping.toJS()创建并返回具有常规属性而非可观察对象的对象。 然后,我们将此对象添加到电话列表中,并清除currentPhone的属性,以使其反映在视图中。
第四步
在这一步中,我们将允许用户从列表中删除电话。 使用以下功能可以完成此操作。
self.removePhone = function() {self.phones.remove(this);
}; 在这里, this代表我们表中将要删除的特定行。
第5步
接下来,添加以下标记:
Name OS Price Remove
Add a new Phone
在此标记中,我们使用了foreach数据绑定,该数据绑定遍历电话列表并显示它们。 我们还使用了click绑定从表中删除了一个项目。 这将在我们的ViewModel上调用removePhone()函数。 当我们进入foreach绑定内部时,已经为我们创建了一个新的上下文。 为了获得对根ViewModel的引用,我们使用$parent 。
接下来要注意的是submit绑定。 单击提交按钮时,这可以防止通常的表单提交过程。 这使我们可以指定将被调用的自定义函数。 在这种情况下,将调用addPhone() ,添加一个新电话。 在表单内部,我们有三个输入字段,它们与currentPhone属性同步。 因此,只要有人按下“提交”按钮,我们就会在currentPhone对象中获得详细信息,只需将其发送到我们的电话列表中即可。
第6步
使用以下代码激活淘汰赛,并观察一切正常!
ko.applyBindings(new PhonesViewModel()); 结论
KnockoutJS绝对是使用MVVM模式构建动态UI的绝佳框架。 本教程介绍了该库的基础知识,但是您肯定应该了解一些高级概念。 以下资源可以为您提供帮助:
- 计算的观测值的详细信息 。
- 详细的声明式绑定语法 。
- 使用JSON 。
可以在GitHub上找到本文演示的完整源代码。
From: https://www.sitepoint.com/understanding-knockout/
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
