Only 30 lines of code implement MVC_JAVASCRIPT techniques in JavaScript

Source: Internet
Author: User

From about 09 onwards, MVC gradually shine in front of the field, and finally in the past 2015 with the introduction of react native ushered in a major outbreak: Angularjs, Emberjs, Backbone, Reactjs, Riotjs, Vuejs ... A series of names have come and gone, some of them have faded out of sight, some are growing fast, and some have independently am in particular ecological environments. However, MVC has and will continue to profoundly influence the way engineers think and work in front of them.

Many examples of MVC are starting with a concept of a specific framework, such as Backbone's collection or ANGULARJS model, which is certainly a good idea. But the framework is the framework, not the class library (JQuery) or toolset (underscore), because they have many excellent design concepts and best practices, the essence of these design is complementary, interlocking, indispensable, It is not easy to see the nature of a design pattern in a short time through a complex framework.

This is the origin of this essay-to help you understand the concept of the prototype code, the simpler the better, simple enough to understand this concept is enough.

1. MVC is based on the observer model, which is the key to implementing model and view synchronization
for the sake of simplicity, only one primitive value value is included in each model instance.

function Model (value) {
  This._value = typeof value = = ' undefined '? ': value;
  This._listeners = [];
}
Model.prototype.set = function (value) {
  var self = this;
  Self._value = value;
  When the value in model changes, you should notify the registered callback function//in
  accordance with the general mechanism of JavaScript event processing, we asynchronously call the callback function
  ///If we feel settimeout affect performance, You can also use Requestanimationframe
  settimeout (function () {
    Self._listeners.foreach (function (listener) {
      Listener.call (self, value);}
    );
  };
Model.prototype.watch = function (listener) {
  //register the listener callback function
  This._listeners.push (listener);
HTML code:
<div id= "Div1" ></div>
//Logical Code:
(Function () {
  var model = new Model ();
  var div1 = document.getElementById (' Div1 ');
  Model.watch (function (value) {
    div1.innerhtml = value;
  });
  Model.set (' Hello, this is a div ');
} ();

With the observer pattern, we have implemented the model's set method to change its value, the template is also synchronized update, but this implementation is very awkward, because we need to manually monitor the model value changes (through the Watch method) and pass in a callback function, Is there a way to make view (one or more DOM node) and model easier to bind?

2. Implement the Bind method, bind model and view

Model.prototype.bind = function (node) {
  //place watch logic and common callback functions here
  This.watch (function (value) {
    node.innerhtml = value;
  };
HTML code:
<div id= "Div1" ></div>
<div id= "div2" ></div>
//Logical code:
( function () {
  var model = new Model ();
  Model.bind (document.getElementById (' Div1 '));
  Model.bind (document.getElementById (' div2 '));
  Model.set (' is a div ');
} ();

With a simple encapsulation, the binding between view and model is beginning to take shape, even if you need to bind multiple view, it is easy to achieve. Note that bind is a function class prototype a native method, but it and MVC is not closely related, I really like the word bind, a language, concise, so simply in here the original method coverage, we can ignore. Anyway, although the complexity of the binding is reduced, this step still relies on us to do it manually, is it possible to completely decouple the logic of the binding from the business code?

3. Implement controller, decoupling the bindings from the logical code

Careful friends may have noticed that, although it is about MVC, but the model class is only shown above, the view class does not appear to be understandable, after all, HTML is ready-made view (in fact this article from beginning to end is just using HTML as view, The JavaScript code does not appear in the view class, so why is the controller class invisible? Don't worry, the so-called "logic code" is a framework logic (let's call this article's prototype toy as a framework) and business logic coupled with a high degree of code snippets, now we have to break it down.
If you want to give the binding logic to the framework to complete, you need to tell the framework how to complete the binding. Because JS is more difficult to complete annotation (annotations), we can do this in view of the tag--the use of HTML tag properties is a simple and effective way.

function Controller (callback) {
  var models = {};
  Find all elements with bind attribute
  var views = Document.queryselectorall (' [bind] ');
  Treat views as normal array views
  = Array.prototype.slice.call (views, 0);
  Views.foreach (function (view) {
    var modelname = View.getattribute (' bind ');
    Remove or create the model models[modelname that the element is bound to
    ] = Models[modelname] | | New model ();
    Complete the binding
    models[modelname].bind (view) of the element and the specified model
  ;
  Call the controller's specific logic and pass models in to facilitate business processing
  callback.call (this, models);
}




HTML:
<div id= "Div1" bind= "Model1" ></div>
<div id= "Div2" bind= "Model1" ></div>
//Logical code:
new Controller (function (models) {
  var model1 = Models.model1;
  Model1.set (' is a div ');
};


Is it that simple? It's as simple as that. The essence of MVC is to complete the business logic in the controller, and modify the model, at the same time the model changes to cause view Automatic Update, these logic in the above code are embodied, and support multiple view, multiple model. It's not enough for a production project, but hopefully it will help you learn a lot about MVC.

Remove the "frame" code for the annotation after sorting:

function Model (value) {
  This._value = typeof value = = ' undefined '? ': value;
  This._listeners = [];
}
Model.prototype.set = function (value) {
  var self = this;
  Self._value = value;
  settimeout (function () {
    Self._listeners.foreach (function (listener) {
      listener.call (self, value);
    });
  });
};
Model.prototype.watch = function (listener) {
  This._listeners.push (listener);
};
Model.prototype.bind = function (node) {
  This.watch (function (value) {
    node.innerhtml = value;
  });
function Controller (callback) {
  var models = {};
  var views = Array.prototype.slice.call (Document.queryselectorall (' [bind] '), 0);
  Views.foreach (function (view) {
    var modelname = View.getattribute (' bind ');
    Models[modelname] = Models[modelname] | | New Model ();
    Models[modelname].bind (view);
  Callback.call (this, models);

Postscript:

In the process of learning Flux and redux, I have mastered the use of tools, but I do not know the reason why, but the Reactjs official document has been emphasized "Flux eschews MVC in favor of a unidirectional data Flow "not very understanding, always feel that one-way data flows and MVC does not conflict, do not understand why in the Reactjs document in the two will be opposed to, there is no me, I have no him (eschew, avoid)." Finally determined to return to the definition of MVC to study, although the weekday work in a careless copy and paste, but we occasionally have to self-willed one, the wording, right? And it does help my understanding of this sentence, here we can share our thoughts with you: it is possible to think that the one-way data flows in MVC and flux are similar, because the--mvc of the relationship between MVC and the Observer model is based on the observer pattern, flux, So the origin of this similarity is the Observer pattern, not MVC and flux itself. This understanding is also confirmed in the original design pattern of the four-person group: "The" the perhaps best-known example of the Observer patterns appears in Smalltalk model/view/ Controller (MVC), the user interface framework in the SMALLTALK environment [KP88]. MVC ' Model class plays the role of Subject, while View is the base class for observers. "。

If the reader is interested in developing such a prototype toy, you can refer to some of the following directions:

    • 1. Realize bidirectional binding to input class label
    • 2. Achieve precise control of the scope controlled by controller, where a controller controls the entire DOM tree
    • 3. Implement the view layer's logic for DOM node hide/show, create/Destroy
    • 4. Integrate virtual DOM, increase the function of Dom diff, Improve rendering efficiency
    • 5. Provide dependency injection function to achieve control reversal
    • 6. innerHTML of the value of the content of security checks to prevent malicious injection
    • 7. Implement model collection logic, here each model has only one value
    • 8. Using the setter in the ES5 to change the set method, making the model more simple to modify
    • 9. Increase control of attributes and CSS in the view layer
    • 10. Support syntax similar to ANGULARJS with double braces, only partially HTML bound
    • ......

A perfect framework to go through countless refining and modification, here is only the first initial step, the road is still very long, I hope you make efforts.

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: info-contact@alibabacloud.com 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.