评论删除后,数据将无法恢复
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.
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.
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:
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.
Less proprietary idioms, more straightforward JavaScript. It's way more important to master universal programming skills instead of some framework's own, opinionated rules.
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.
Embeddable. Use Riot.js everywhere without additional bloat. Framework should not be bigger than the application itself.
Faster. According to Google, each kilobyte of JavaScript adds 1ms of parse time to the overall page load time (1).
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.
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.
Riot uses Model-View-Presenter (MVP) design pattern to organize your code so that it's modular, testable and easy to understand.
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:
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.
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.
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.
The observable call adds following methods to the given object:
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.
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.
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.
评论删除后,数据将无法恢复
评论(53)
Riot现在发展如何?
引用来自“Jackx”的评论
收藏了,以后一定用得到滴