mirror of
https://github.com/apachecn/modern-java-zh.git
synced 2025-06-07 18:11:07 +00:00
ch10
This commit is contained in:
parent
af0baf706e
commit
c1701ec2e4
109
ch10.md
Normal file
109
ch10.md
Normal file
@ -0,0 +1,109 @@
|
||||
# 在 Nashron 中使用 Backbone.js
|
||||
|
||||
> 原文:[Using Backbone.js with Nashorn](http://winterbe.com/posts/2014/04/07/using-backbonejs-with-nashorn/)
|
||||
|
||||
> 译者:[飞龙](https://github.com/wizardforcel)
|
||||
|
||||
> 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/)
|
||||
|
||||
这个例子展示了如何在Java8的Nashron JavaScript引擎中使用Backbone.js模型。Nashron在2014年三月首次作为Java SE 8 的一部分发布,并通过以原生方式在JVM上运行脚本扩展了Java的功能。对于Java Web开发者,Nashron尤其实用,因为它可以在Java服务器上复用现有的客户端代码。传统的[Node.js](http://nodejs.org/)具有明显优势,但是Nashorn也能够缩短JVM的差距。
|
||||
|
||||
当你在HTML5前端使用现代的JavaScript MVC框架,例如[Backbone.js](http://backbonejs.org/)时,越来越多的代码从服务器后端移动到Web前端。这个方法可以极大提升用户体验,因为在使用视图的业务逻辑时节省了服务器的很多往返通信。
|
||||
|
||||
Backbone允许你定义模型类,它们可以用于绑定视图(例如HTML表单)。当用户和UI交互时Backbone会跟踪模型的升级,反之亦然。它也能通过和服务器同步模型来帮助你,例如调用服务端REST处理器的适当方法。所以你最终会在前端实现业务逻辑,将你的服务器模型用于处理持久化数据。
|
||||
|
||||
在服务端复用Backbone模型十分容易用Nashron完成,就像下面的例子所展示的那样。在我们开始之前,确保你通过阅读我的[Nashorn教程](ch3.md)熟悉了在Nashron引擎中编程JavaScript。
|
||||
|
||||
## Java 模型
|
||||
|
||||
首先,我们在Java中定义实体类`Product`。这个类可用于数据库的CURD操作(增删改查)。要记住这个类是个纯粹的Java Bean,不实现任何业务逻辑,因为我们想让前端正确执行UI的业务逻辑。
|
||||
|
||||
```java
|
||||
class Product {
|
||||
String name;
|
||||
double price;
|
||||
int stock;
|
||||
double valueOfGoods;
|
||||
}
|
||||
```
|
||||
|
||||
## Backbone 模型
|
||||
|
||||
现在我们定义Backbone模型,作为Java Bean的对应。Backbone模型`Product`使用和Java Bean相同的数据结构,因为它是我们希望在Java服务器上持久存储的数据。
|
||||
|
||||
Backbone模型也实现了业务逻辑:`getValueOfGoods`方法通过将`stock`于`price`相乘计算所有产品的总值。每次`stock`或`price`的变动都会使`valueOfGoods`重新计算。
|
||||
|
||||
```js
|
||||
var Product = Backbone.Model.extend({
|
||||
defaults: {
|
||||
name: '',
|
||||
stock: 0,
|
||||
price: 0.0,
|
||||
valueOfGoods: 0.0
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
this.on('change:stock change:price', function() {
|
||||
var stock = this.get('stock');
|
||||
var price = this.get('price');
|
||||
var valueOfGoods = this.getValueOfGoods(stock, price);
|
||||
this.set('valueOfGoods', valueOfGoods);
|
||||
});
|
||||
},
|
||||
|
||||
getValueOfGoods: function(stock, price) {
|
||||
return stock * price;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
由于Backbone模型不使用任何Nashron语言扩展,我们可以在客户端(浏览器)和服务端(Java)安全地使用同一份代码。
|
||||
|
||||
要记住我特意选择了十分简单的函数来演示我的意图。真实的业务逻辑应该会更复杂。
|
||||
|
||||
## 将二者放在一起
|
||||
|
||||
下一个目标是在Nashron中,例如在Java服务器上复用Backbone模型。我们希望完成下面的行为:把所有属性从Java Bean上绑定到Backbone模型上,计算`valueOfGoods`属性,最后将结果传回Java。
|
||||
|
||||
首先,我们创建一个新的脚本,它仅仅由Nashron执行,所以我们这里可以安全地使用Nashron的扩展。
|
||||
|
||||
```js
|
||||
load('http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js');
|
||||
load('http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js');
|
||||
load('product-backbone-model.js');
|
||||
|
||||
var calculate = function(javaProduct) {
|
||||
var model = new Product();
|
||||
model.set('name', javaProduct.name);
|
||||
model.set('price', javaProduct.price);
|
||||
model.set('stock', javaProduct.stock);
|
||||
return model.attributes;
|
||||
};
|
||||
```
|
||||
|
||||
这个脚本首先加载了相关的外部脚本[Underscore](http://underscorejs.org/) 和 [Backbone](http://backbonejs.org/)(Underscore是Backbone的必备条件),以及我们前面的`Product`Backbone模型。
|
||||
|
||||
函数`calcute`接受`Product`Java Bean,将其所有属性绑定到新创建的Backbone`Product`上,之后返回模型的所有属性给调用者。通过在Backbone模型上设置`stock`和`price`属性,`ValueOfGoods`属性由于注册在模型`initialize`构造函数中的事件处理器,会自动计算出来。
|
||||
|
||||
最后,我们在Java中调用`calculate`函数。
|
||||
|
||||
```java
|
||||
Product product = new Product();
|
||||
product.setName("Rubber");
|
||||
product.setPrice(1.99);
|
||||
product.setStock(1337);
|
||||
|
||||
ScriptObjectMirror result = (ScriptObjectMirror)
|
||||
invocable.invokeFunction("calculate", product);
|
||||
|
||||
System.out.println(result.get("name") + ": " + result.get("valueOfGoods"));
|
||||
// Rubber: 2660.63
|
||||
```
|
||||
|
||||
我们创建了新的`Product`Java Bean,并且将它传递到JavaScript函数中。结果触发了`getValueOfGoods`方法,所以我们可以从返回的对象中读取`valueOfGoods`属性的值。
|
||||
|
||||
## 总结
|
||||
|
||||
在Nashron中复用现存的JavaScript库十分简单。Backbone适用于构建复杂的HTML5前端。在我看来,Nashron和JVM现在是Node.js的优秀备选方案,因为你可以在Nashron的代码库中充分利用Java的整个生态系统,例如JDK的全部API,以及所有可用的库和工具。要记住你在使用Nashron时并不限制于Java -- 想想 Scala、Groovy、Clojure和`jjs`上的纯JavaScript。
|
||||
|
||||
这篇文章中可运行的代码托管在[Github](https://github.com/winterbe/java8-tutorial)上(请见[这个文件](https://github.com/winterbe/java8-tutorial/blob/master/res/nashorn6.js))。请随意[fork我的仓库](https://github.com/winterbe/java8-tutorial/fork),或者在[Twitter](https://twitter.com/winterbe_)上向我反馈。
|
Loading…
x
Reference in New Issue
Block a user