Riot.js — 1Kb 大小的 JavaScript 的 MVP 框架 已翻译 100%

oschina 投递于 2013/11/02 18:24 (共 17 段, 翻译完成于 11-10)
阅读 21041
收藏 374
43
加载中

An incredibly fast, powerful yet tiny client side framework for building large scale web applications.

Riot.js is a client-side Model-View-Presenter (MVP) framework that weighs less than 1kb. Despite the unbelievable size, all the building blocks are there: a template engine, router, event library and a strict MVP pattern to keep things organized. Your views are automatically updated when the underlying model changes.

Riot.js is faster and simpler — in fact, on a completely different scale — and applications built with it are also faster and simpler. For real.

Let's go deeper.

已有 2 人翻译此段
我来翻译

Fastest

Riot.js comes with the fastest JavaScript templating engine that currently exists. It's ~5 times faster than Resig's "micro templating" or ~7 times faster than Underscore.

Templating affects the rendering time of your application. Faster templating makes for a faster app. On bigger applications the difference can be huge, especially on non- Webkit browsers. The above test can take 1300ms in Hogan and 30ms in Riot with 100k repeats on Firefox. Please try the above test with different browsers to get a better picture.

已有 1 人翻译此段
我来翻译

Smallest

Here is how Riot stack up to some of the popular client-side frameworks.

Riot is the smallest by a clear margin, and the size of a framework does matter:

  1. Less to learn. Fewer books and tutorials to view. The difference here is enormous: think 3 API methods instead of 300. You'll spend more time building the actual application. Essential for bigger teams. Projects can fail due to wrong decisions.

  2. Less proprietary idioms, more straightforward JavaScript. It's way more important to master universal programming skills instead of some framework's own, opinionated rules.

  3. Less bugs. Less vulnerable surface and weak spots. All bugs should be user bugs. It's frustrating when your application fails because of a bug on the framework.

  4. Embeddable. Use Riot.js everywhere without additional bloat. Framework should not be bigger than the application itself.

  5. Faster. According to Google, each kilobyte of JavaScript adds 1ms of parse time to the overall page load time (1).

  6. Cheaper. Amazon.com increased its revenue by 1% for every 100 milliseconds of load time improvement (2). In 2012, 1% of Amazon’s revenues amounted to $610.9 Million

If you are building a tool for others' consumption, size is even more important.

已有 1 人翻译此段
我来翻译

Most powerful

Here's the shocking part: a 1Kb library requires the least keystrokes to build the Todo MVC application:

The size of the required application code gives a good picture of the capabilities of a framework. The whole purpose of a framework is to solve common problems so users won't have to reinvent the wheel. Write less, achieve more.

The size of the code obviously depends on multiple factors such as the programming style, so honestly your goal should not be small, but simple.

And simplicity is where Riot really shines.

已有 1 人翻译此段
我来翻译

MVP design pattern

Riot uses Model-View-Presenter (MVP) design pattern to organize your code so that it's modular, testable and easy to understand.

Model View Presenter

Just like in MVC (Model View Controller) or MVVM (Model View ViewModel), the purpose is to separate your application logic from the view, but MVP is simpler. Let's take MVC for comparison:

Model View Controller

MVC is more complex. The many arrows form a circle. The role of the controller is not clear, and the pattern can be interpreted in many different ways. In fact, this is the root cause for the explosion of client-side frameworks.

MVP, on the other hand, has less room for interpretation. The role of each part is clear. It works for big and small projects, and is the best pattern for unit tests.

Let's see how MVP works in Riot.

已有 1 人翻译此段
我来翻译

Model

Riot models define your application. It's your business logic exposed to outer world with a well-thought API. A completely isolated, testable unit that can be run in browser and server (node.js). Here is one for the Todo app.

function Todo(store) {
 
   var self = this,
      items = [];
 
   self.add = function(label) {
      var item = { ... };
      items.push(item);
 
      // notify others
      self.emit("add", item);
   }
 
   self.remove = function(id) {
      delete items[id];
      self.emit("remove", item);
   }
 
   // + other public methods ...
 

   // Enable MVP pattern (this is the secret for everything)
   $.observable(self);
 
   // save state
   self.on("add remove edit", function() {
      store.put(items);
   })
 
}

The Model is a plain old JavaScript object (POJO) without framework specific idioms. In MVC terminology it's a domain model  rather than just a data access layer.

You have the freedom to build your models in your preferred way using theprototypeobject or the object constructor{}. The above is just my personal style of writing JavaScript.

When designing a model it's important to clean your mind. The last thing you want is a framework to steal your focus. It's your precious business logic! JavaScript has tremendous expressive power in itself.

已有 1 人翻译此段
我来翻译

The observable

Observables are they key for separating the model from the rest of your application:

$.observable(object); 

After the above call the given object is able to notify others when something crucial happens. The views can re-render themselves or the users of the API users can make their extensions by listening to the changes.

Observables are the key to splitting your app into maintainable components. It's a classic design pattern to separate the Model from the View.

"The secret to building large apps is never build large apps. Break your applications into small pieces" — Justin Meyer, author of JavaScriptMVC

"The more tied components are to each other, the less reusable they will be, and the more difficult it becomes to make changes to one without accidentally affecting another" — Rebecca Murphey, author of jQuery Fundamentals

A good event library is the single most important feature in a client-side framework. And this is where Riot places the biggest focus.

已有 1 人翻译此段
我来翻译

The observable call adds following methods to the given object:

  • emit(event_name, args...)— trigger a named event with optional arguments
  • on(event_name, fn)— call the given function when a particular event is triggered
  • one(event_name, fn)— call the given function once when a particular event is triggered. additional events cause no action
  • off(event_name)— stop listening to a specified event

Riot events are based on jQuery events, so all the powerful features are there, such as namespaces , and the ability to listen to multiple events at once.

The most important difference is that there is noEvent object because it's not relevant outside the DOM. You can also send and receive arguments nicely without wrapping them to an array:

// send event
obj.emit("my-event", "1st argument", "2nd arg", ... argN);
 
// receive event
obj.on("my-event", function(arg1, arg2, ... argN) {
 
});
Observables were introduced in 1988 by Smalltalk and have been used to build user interfaces ever since. It's a design pattern, not a framework. Events and listeners are the essence of good code with separated concerns. They should be a core part of your mindset.

Let me put this in another way:

You don't need a framework to write modular client-side applications.

已有 1 人翻译此段
我来翻译

View

View is the visible part of your application. Text, images, tables, buttons, links and the like. The HTML and the CSS.

Riot views are as dummy as possible. No conditional statements, loops, or data binding. No custom attributes or custom elements. These should be absent from the view. Views are something you can expect from any HTML developer.

There are only "templates" — fragments of HTML that can be inserted in the view at runtime. These templates contain variables that are substituted with data using the extremely fast Riot template engine.

Here's one for a single TodoMVC entry:

<li id="{id}">
   <div class="view">
      <input class="toggle" type="checkbox">
      <label>{name}</label>
      <button class="destroy"/>
   </div>
   <input class="edit" value="{name}">
</li>
This kind of "logicless HTML" has no weak spots or testable surface. It's faster and passes W3C validator.

The actual logic is inside the presenter.

已有 1 人翻译此段
我来翻译

Presenter

Presenter listens to what happens on the View (click, scroll, keyboard, back button etc) and on the Model (things are added, removed or modified) and it updates both view and model accordingly. This "middleman" explicitly defines how the user interface behaves. Here's one for the Todo app:

$(function() {
 
   / 1. Initialize /
 
   // create a model instance
   var model = new Todo(),
 
      // Grab the HTML root of this view
      root = $("#todo-list"),
 
      // HTML template for a single todo- entty
      template = $("#todo-tmpl").html(),
 

   / 2. Listen to user events /
 
   // "clear completed" is clicked
   $("#clear-completed").click(function() {
      todo.remove("completed");
   })
 
   // "toggle all" is clicked
   $("#toggle-all").click(function() {
      todo.toggle(filter);
   })
 
   // ...
 

   / 3. Listen to model events /
 

   // an entry was removed
   todo.on("remove", function(items) {
      $.each(items, function() {
         $(this.id).remove()
      })
 
   // an entry was edited
   }).on("edit", function(item) {
      var el = $(item.id);
      el.removeClass("editing");
      $("label, .edit", el).text(item.name).val(item.name);
   })
 
   // ...
 
})
I have put all the logic inside a single presenter, but there can be multiple presenters performing a separate task. For example, I could have put all the logic for a single todo entry in a separate file.

Feel free to decide the role of each presenter that makes the most sense for your application. This can be based on the role on the UI (sidebar, account, header...) or based on functionality (login, join, create, remove...).

Presenter has all the user interface logic, expressed with jQuery.

已有 1 人翻译此段
我来翻译
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(53)

黑暗料理魔王
黑暗料理魔王
哪些网站有应用了riot.js
magoo_lau
magoo_lau
mark
红薯官方
红薯官方
avalon.js也相当简单的。
小小黄鸡
小小黄鸡
然而,三年已经过去了~
Riot现在发展如何?
小小黄鸡
小小黄鸡
路由还需要自己进行正则匹配,这点不太好吧~
hackaday
hackaday
roitjs中推出了tag的概念,html代码又和js逻辑写到一块去了,感觉已经失去了当初喜欢上他的理由。
liango
liango
roitjs现在已经可以很好的运行于产品环境了吗?
开源中国匿名会员
开源中国匿名会员

引用来自“Jackx”的评论

收藏了,以后一定用得到滴
过了两年,用到了没有?
Jackx
Jackx
收藏了,以后一定用得到滴
Jackx
Jackx
不明觉厉呀!!
返回顶部
顶部