View-model in Javascript

Source: Internet
Author: User
Document directory
  • Model
  • View
  • Template
  • Asynchronous task

This is a very common Weibo list page, similar to Sina Weibo. Last weekend, a total of five objects were used to generate 400 lines of code, and a code organization mode was developed.

The code for easy task completion consists of four elements:

Elements Composition
Model Reply, forward
View Commenteditor, replylist, and forwardlist
Template Jquery. tmpl
Asynchronous task Jquery. Deferred
Division Introduction Model

A model is only related to data. It can generate, filter, store, and verify data.

For example, when the message model calls the Save method, it only receives JSON parameters and returns only one asynchronous task. In actual processing, synchronous or asynchronous return results are not important.

The reason for this verification is that it is an open object and the last threshold for interaction with the server.

In addition, it does not handle the verification failure itself-it is selectively processed by the view when calling, a message prompt may pop up or ignore it directly and try again.

// Message Model VaR reply = {cache :{}, // {sourceid: ID, page_size: 10, page_num: 1} fetch: function (data) {return $. post ('/ajax/blog/reply/list', data || {}). success (function (RESP) {resp. OK & resp. list & $. each (resp. list, function (K, v) {return reply. cache [v. id] = V ;}) ;}, // filter ('name', 'King') filter: function (prop, Val) {return $. grep (this. cache, function (r) {return R [prop] = Val}) ;}, // {content: 'Whatever you want to say ', sourceid: 1001} create: function (data) {// promise var DFD = $. deferred (), now = $. now (); If (now-this. create. time stamp)/1000

A view is a visible part of a browser page. Each view object contains an associated jquery object as an attribute (instance. $ El), similar to the DOM container in the UI component.

There are two ways to make the view consistent:

  • The render method is used to obtain data from the model and render the data to the HTML page according to the defined template.
  • The activate method is used to activate a view and bind related DOM events. All events are delegated to $ El at most.

In this example, commenteditor is the parent view, and replylist and forwardlist are two child views that are mutually exclusive. The Parent and Child views store references to each other.

// Return list view var replylist = function (options) {var opt = This. opt = $. extend ({El: '', parent: NULL}, options ||{}); this. parent = OPT. parent; this. $ El = $ (OPT. el); this. activate () ;}; replylist. prototype = {render: function () {var self = This; reply. fetch ({page_size: 10, page_num: 1, sourceid: Self. parent. getblogid ()}). done (function (data) {self.$el.html (self. $ list = $. tmpl (tpl_reply_list, data) ;}); return self ;}, activate: function () {This. $ el. delegate ('a. del ', $. proxy (this. del, this ))}//...} // commenteditor in the comment editor view. prototype = {activate: function () {This. $ el. delegate ('a. save ', $. proxy (this. save, this)}, save: function () {var self = This, Data = {content: Self. getcontent (), sourceid: Self. getblogid ()}; var task_r = reply. create (data); var task_f = forward. create (data); // forward and comments at the same time $. when (task_r, task_f ). then (function (T1, T2) {// save successfully, update view or close}, function (data) {// model verification error, or remote server error (data. message, Data. type) ;}); return self ;}, switchview: function (type) {// switch the subview var view_opt = {El: This. $ sublist. empty (), parent: This}; If (type = 'reply') {$ label. show (); this. $ submit. val ('comments'); this. sublist = new replylist (view_opt ). render ();} else {$ label. hide (); this. $ submit. val ('forwarder '); this. sublist = new forwardlist (view_opt ). render ();}}//...}

The template can eliminate tedious and ugly String concatenation. Its function is to generate HTML fragments directly from JS objects.

The template can directly traverse objects and apply predefined functions to format some data, such as the time function nicetime:

// Reply list template var tpl_reply_list = '<ul class = "UI-reply-list" >\{{ each list }\< Li data-id = "$ {ID} ">\< a class =" name "href ="/$ {userid} ">$ {name }: </a >\< P >$ {content} </P >\< time pubdate >$ {nicetime (timestamp )} </time> <a class = "Del" href = "javascript :; "> Delete </a >\</Li >\{{/each }}\</ul> ';
Asynchronous task

The literal translation of a deferred object is a delayed object, but it is more appropriate to understand it as an asynchronous task. Asynchronous tasks can eliminate multi-layer nested callbacks, making code writing and reading more convenient.

From the above model and view code, we can see that after an asynchronous task is used, the Code becomes more flat.

$. The deferred method creates a two-way task queue: The success callback function queue and the Failure callback function queue. The task status is divided into two types: success and failure, you can use isresolved or isrejected to check the current status of the task, and use resolve or reject to modify the status of the task.

The promise method returns the read-only copy of the task, which cannot be changed. There is no doubt that the model should always return only the promise object. (Note: Read-Only copies can still be returned again by calling the promise method)

In the reply. Create method, you can better process custom asynchronous tasks rather than directly returning native Ajax asynchronous tasks:

// Var DFD = $. deferred (); $. post ('/ajax/blog/reply/create', data ). success (function (JSON) {If (JSON & JSON. OK) {DFD. resolve (JSON. list);} else {DFD. reject ({message: JSON. message | 'retrieval failed', type: 'error '});}}). fail (function () {DFD. reject ({message: 'service temporarily unavailable ', type: 'error '})});
Objective and conclusion

Why is this split?

Gains: maintainability, clear API calls, elimination of IF Statements at or above the second layer, elimination of callback statements at or above the second layer, and control each function within 20 rows.

Result: No code is repeated, and all functions are packaged.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.