开发者社区> 杰克.陈> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

【ASP.NET Web API教程】2.3.5 用Knockout.js创建动态UI

简介: 原文:【ASP.NET Web API教程】2.3.5 用Knockout.js创建动态UI 注:本文是【ASP.NET Web API系列教程】的一部分,如果您是第一次看本博客文章,请先看前面的内容。
+关注继续查看
原文:【ASP.NET Web API教程】2.3.5 用Knockout.js创建动态UI

注:本文是【ASP.NET Web API系列教程】的一部分,如果您是第一次看本博客文章,请先看前面的内容。

Part 5: Creating a Dynamic UI with Knockout.js
第5部分:用Knockout.js创建动态UI

本文引自:http://www.asp.net/web-api/overview/creating-web-apis/using-web-api-with-entity-framework/using-web-api-with-entity-framework,-part-5

Creating a Dynamic UI with Knockout.js
用Knockout.js创建动态UI

In this section, we'll use Knockout.js to add functionality to the Admin view.
在本小节中,我们将用Knockout.js对Admin视图添加功能。

Knockout.js is a Javascript library that makes it easy to bind HTML controls to data. Knockout.js uses the Model-View-ViewModel (MVVM) pattern.
Knockout.js是一个JavaScript库,它让HTML控件很容易与数据进行绑定。Knockout.js使用的是“模型-视图-视图模型(MVVM)”模式。

  • The model is the server-side representation of the data in the business domain (in our case, products and orders).
    模型是事务域中数据的服务器端表示(在我们的示例中,是产品和订单)。
  • The view is the presentation layer (HTML).
    视图是表现层(HTML)。
  • The view-model is a Javascript object that holds the model data. The view-model is a code abstraction of the UI. It has no knowledge of the HTML representation. Instead, it represents abstract features of the view, such as "a list of items".
    视图模型是保存了模型数据的一个JavaScript对象。视图模型是UI的一种代码抽象。它没有HTML表示方面的知识,但它表现了视图的抽象特性,如“列表项”。

The view is data-bound to the view-model. Updates to the view-model are automatically reflected in the view. The view-model also gets events from the view, such as button clicks, and performs operations on the model, such as creating an order.
视图是与视图模型数据绑定的。对视图模型的更新会自动地在视图得到反映。视图模型也会获取视图的事件,如按钮点击,并在模型上执行操作(见图2-23)。

WebAPI2-23

图2-23. 模型-视图-视图模型之间的关系

First we'll define the view-model. After that, we will bind the HTML markup to the view-model.
首先,我们要定义视图模型。之后,要将HTML标记与视图模型进行绑定。

Add the following Razor section to Admin.cshtml:
对Admin.cshtml添加以下Razor片段:

@section Scripts {
  @Scripts.Render("~/bundles/jqueryval") 
  <script type="text/javascript" src="@Url.Content("~/Scripts/knockout-2.1.0.js")"></script>  
  <script type="text/javascript"> 
  // View-model will go here 
  // 视图模型会放在这儿
  </script> 
}

You can add this section anywhere in the file. When the view is rendered, the section appears at the bottom of the HTML page, right before the closing </body> tag.
可以把这个片断添加到文件的任何地方。当视图被渲染时,这个片段会出现在HTML页面的底部,</body>关闭标签的前面。

All of the script for this page will go inside the script tag indicated by the comment:
用于这个页面的所有脚本都被放在由以下注释所指示的script标签中:

<script type="text/javascript"> 
    // View-model will go here
    // 视图模型会放在这儿
 </script>

First, define a view-model class:
首先,定义一个视图模型类:

function ProductsViewModel() { 
    var self = this; 
    self.products = ko.observableArray(); 
}

ko.observableArray is a special kind of object in Knockout, called an observable. From the Knockout.js documentation: An observable is a “JavaScript object that can notify subscribers about changes.” When the contents of an observable change, the view is automatically updated to match.
ko.observableArray是Knockout中的一种叫做observable的特殊对象(请将这种observable对象称为可见对象。这种对象往往作为视图模型与视图进行交互,对视图而言,它是透明可见的,故称为可见对象。在以下翻译中,都将这种observable对象称为可见对象 — 译者注)。根据Knockout.js文档的描述:可见对象是一种“能够通知订户数据变化情况的JavaScript对象”。当一个可见对象的内容发生变化时,视图会自动地进行匹配更新。

To populate the products array, make an AJAX request to the web API. Recall that we stored the base URI for the API in the view bag (see Part 4 of the tutorial).
为了填充Products数组,需要形成一个发送到Web API的请求。调回我们在视图包(View Bag)中存储的、用于此API的基URI(见本教程的第4部分)。

function ProductsViewModel() { 
    var self = this; 
    self.products = ko.observableArray(); 
// New code // 新代码 var baseUri = '@ViewBag.ApiUrl'; $.getJSON(baseUri, self.products); }

Next, add functions to the view-model to create, update, and delete products. These functions submit AJAX calls to the web API and use the results to update the view-model.
下一步,对视图模型添加创建、更新以及删除产品的函数。这些函数会对Web API递交AJAX调用,并使用(所得到的)结果对视图模型进行更新。

function ProductsViewModel() { 
    var self = this; 
    self.products = ko.observableArray(); 
var baseUri = '@ViewBag.ApiUrl';
// New code // 新代码 self.create = function (formElement) { // If the form data is valid, post the serialized form data to the web API. // 如果表单数据有效,把序列化的表单数据递交给Web API $(formElement).validate(); if ($(formElement).valid()) { $.post(baseUri, $(formElement).serialize(), null, "json") .done(function (o) { // Add the new product to the view-model. // 将新产品添加到视图模型 self.products.push(o); }); } }
self.update = function (product) { $.ajax({ type: "PUT", url: baseUri + '/' + product.Id, data: product }); }
self.remove = function (product) { // First remove from the server, then from the view-model. // 首先从服务器删除,然后从视图模型删除 $.ajax({ type: "DELETE", url: baseUri + '/' + product.Id }) .done(function () { self.products.remove(product); }); }
$.getJSON(baseUri, self.products); }

Now the most important part: When the DOM is fulled loaded, call the ko.applyBindings function and pass in a new instance of the ProductsViewModel:
现在,最重要的部分:当DOM全部装载时,调用ko.applyBindings函数,并在其中传递一个新的ProductsViewModel实例:

$(document).ready(function () {
    ko.applyBindings(new ProductsViewModel());
})

The ko.applyBindings method activates Knockout and wires up the view-model to the view.
ko.applyBindings方法会激活Knockout,并将视图模型与视图连接起来。

Now that we have a view-model, we can create the bindings. In Knockout.js, you do this by adding data-bind attributes to HTML elements. For example, to bind an HTML list to an array, use the foreach binding:
现在,我们有了一个视图模型,于是可以创建绑定(这里的绑定含义是将视图模型中的数据项与视图中的各个HTML控件进行绑定 — 译者注)。在Knockout.js中,通过把data-bind标签属性(标签属性是指HTML元素的属性,这样翻译的目的也是与类的属性有所区别 — 译者注)添加到HTML元素的办法来做这件事。例如,要把一个HTML列表绑定到一个数据,使用foreach绑定:

<ul id="update-products" data-bind="foreach: products">

The foreach binding iterates through the array and creates child elements for each object in the array. Bindings on the child elements can refer to properties on the array objects.
foreach绑定会遍历数组,并为数组中的每个对象创建子元素。在子元素上的绑定可以指向数组对象上的属性。

Add the following bindings to the "update-products" list:
对“update-products”列表添加以下绑定:

<ul id="update-products" data-bind="foreach: products"> 
    <li> 
        <div> 
            <div class="item">Product ID</div> <span data-bind="text: $data.Id"></span> 
        </div> 
        <div> 
            <div class="item">Name</div>  
            <input type="text" data-bind="value: $data.Name"/> 
        </div>  
        <div> 
            <div class="item">Price ($)</div>  <!-- 这里的$表示的美元符字符 — 译者注 -->
            <input type="text" data-bind="value: $data.Price"/> 
        </div> 
        <div> 
            <div class="item">Actual Cost ($)</div>  
            <input type="text" data-bind="value: $data.ActualCost"/> 
        </div> 
        <div> 
            <input type="button" value="Update" data-bind="click: $root.update"/> 
            <input type="button" value="Delete Item" data-bind="click: $root.remove"/> 
        </div> 
    </li> 
</ul>

The <li> element occurs within the scope of the foreach binding. That means Knockout will render the element once for each product in the products array. All of the bindings within the <li> element refer to that product instance. For example, $data.Name refers to the Name property on the product.
<li>元素出现在foreach绑定的范围之内。这意味着Knockout会对products数组中的每个产品渲染一个元素。在<li>元素中的所有绑定指向这个产品实例。例如,$data.Name是指该产品上的Name属性。

To set the values of the text inputs, use the value binding. The buttons are bound to functions on the model-view, using the click binding. The product instance is passed as a parameter to each function. For more information, the Knockout.js documentation has good descriptions of the various bindings.
设置文本输入框的值,要使用value绑定。按钮要绑定到视图模型上的函数,需使用click绑定。产品实例是作为参数传递给每个函数的。对于更多信息,Knockout.js文档对各种绑定有很好的描述。

Next, add a binding for the submit event on the Add Product form:
下一步,为“添加产品”表单上的submit(递交)事件添加一个绑定:

<form id="addProduct" data-bind="submit: create">

This binding calls the create function on the view-model to create a new product.
这个绑定调用视图模型上的create函数,以创建一个新产品。

Here is the complete code for the Admin view:
以下是Admin视图的完整代码:

@model ProductStore.Models.Product
@{ ViewBag.Title = "Admin"; }
@section Scripts { @Scripts.Render("~/bundles/jqueryval") <script type="text/javascript" src="@Url.Content("~/Scripts/knockout-2.0.0.js")"></script> <script type="text/javascript"> function ProductsViewModel() { var self = this; self.products = ko.observableArray();
var baseUri = '@ViewBag.ApiUrl';
self.create = function (formElement) { // If valid, post the serialized form data to the web api // 如果有效,把序列化的表单数据递交(post)给Web API $(formElement).validate(); if ($(formElement).valid()) { $.post(baseUri, $(formElement).serialize(), null, "json") .done(function (o) { self.products.push(o); }); } }
self.update = function (product) { $.ajax({ type: "PUT", url: baseUri + '/' + product.Id, data: product }); }
self.remove = function (product) { // First remove from the server, then from the UI // 先从服务器删除,然后从UI删除 $.ajax({ type: "DELETE", url: baseUri + '/' + product.Id }) .done(function () { self.products.remove(product); }); }
$.getJSON(baseUri, self.products); }
$(document).ready(function () { ko.applyBindings(new ProductsViewModel()); }) </script> }
<h2>Admin</h2> <div class="content"> <div class="float-left"> <ul id="update-products" data-bind="foreach: products"> <li> <div> <div class="item">Product ID</div> <span data-bind="text: $data.Id"></span> </div> <div> <div class="item">Name</div> <input type="text" data-bind="value: $data.Name"/> </div> <div> <div class="item">Price ($)</div> <input type="text" data-bind="value: $data.Price"/> </div> <div> <div class="item">Actual Cost ($)</div> <input type="text" data-bind="value: $data.ActualCost"/> </div> <div> <input type="button" value="Update" data-bind="click: $root.update"/> <input type="button" value="Delete Item" data-bind="click: $root.remove"/> </div> </li> </ul> </div>
<div class="float-right"> <h2>Add New Product</h2> <form id="addProduct" data-bind="submit: create"> @Html.ValidationSummary(true) <fieldset> <legend>Contact</legend> @Html.EditorForModel() <p> <input type="submit" value="Save" /> </p> </fieldset> </form> </div> </div>

Run the application, log in with the Administrator account, and click the "Admin" link. You should see the list of products, and be able to create, update, or delete products.
运行应用程序,用Administrator账号登录,并点击“Admin”链接。应当看到产品列表,并能够创建、更新或删除产品。

看完此文如果觉得有所收获,恳请给个推荐

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
【Python】基于Django Web开发清单
一 简介    最近在和 同事 一起开发一套数据库管理平台 ,该平台使用Django 作为web 框架。和大多数数据库管理平台一样 ,该平台提供 备份,恢复,申请实例,实例上下线  以及数据质量对比 等功能。
1183 0
Java Web开发——网页篇[1]——开始使用MyEclipse
Java Web开发——网页篇[1]——开始使用MyEclipse
6691 0
VS 2017开发ASP.NET Core Web应用过程中发现的一个重大Bug
  今天试着用VS 2017去开发一个.net core项目,想着看看.net core的开发和MVC5开发有什么区别,然后从中发现了一个VS2017的Bug。   首先,我们新建项目,ASP.NET Core Web应用程序,如图: 新建好后,我们按照习惯,在controller文件夹上面,点击鼠标右键,添加控制器...,出现了如下界面:   这个对话框什么意思呢?怎么会提示添加依赖项呢?按理来说,我们直接调试运行,项目就跑起来了!!! 先不管他,我们直接点击添加,然后稍等一会儿,等他添加依赖。
1399 0
python做web开发时用的是什么服务器?
python做web开发时用的是什么服务器? 为什么说这个问题? 今天一个小伙伴提了一个问题,如下图: 这应该是参考我的文章:《Python入门》第一个Python Web程序——简单的Web服务器 但是他想访问执行一个 python 文件,结果呢,把源代码显示出来了! 创建测试文件:test.
785 0
Linux下用gSOAP开发Web Service服务端和客户端程序(一)
1、功能说明:        要开发的Web Service功能非常简单,就是一个add函数,将两个参数相加,返回其和。   2、C版本的程序: (1)头文件:SmsWBS.h,注释部分不可少,url部分的IP必须填写当前Linux电脑的IP //gsoap ns service name...
1026 0
ubuntu下安装 gSOAP 用于C/C++开发web service服务端与客户端
昨天在ubuntu下进行安装gSOAP,费了很多时间,没成功,今天又来找了大量教程资料,终于一次成功,这里写下自己的安装步骤和方法,供大家参考。 首先下载gsoap,我下载的是gsoap-2.8.1.zip 用unzip gsoap-2.8.1.zip命令解压缩,会解压生成gsoap-2.8文件夹。
1236 0
+关注
杰克.陈
一个安静的程序猿~
文章
问答
文章排行榜
最热
最新
相关电子书
更多
WEB浏览器中即将发生的安全变化
立即下载
Web应用系统性能优化
立即下载
从Web到Cloud App——YunOS Web App 开发经验分享
立即下载