Home  >  Article  >  Web Front-end  >  Implementing the MVVM framework in js (detailed tutorial)

Implementing the MVVM framework in js (detailed tutorial)

亚连
亚连Original
2018-06-11 18:00:541840browse

Below I will share with you an example of a simple MVVM framework implemented in js, which has a good reference value and I hope it will be helpful to everyone.

I used to read the articles in the garden silently and like them obscenely. Today I will also share a simple mvvm framework that I implemented using js.

At first, I only did automatic binding events. Later, I learned about vue, knockout and argular implementation methods, and combined with some of my own experience in making WPF, I added attribute binding. Today I sorted it out a little. Improved some functions and submitted the code to Code Cloud: https://gitee.com/zlj_fy/Simple-MVVM

Let’s briefly introduce the usage:

<form class="form-horizontal" role="form" data-context="TestController">
  <p class="form-group">
   <legend>Form title</legend>
  </p>
  <p class="form-group">
   <p class="col-sm-6 col-sm-offset-2">
    <input type="text" class="form-control" bind-val="age,format=format" style="margin:5px 0" />
    <input type="text" class="form-control" bind-val="desc" style="margin:5px 0" />
    <input type="range" min="10" max="300" bind-val="age" step="10" class="form-control" style="margin:5px 0" />
    <input type="button" class="btn btn-primary" value="更新" style="margin:5px 0" on-click="update" />
   </p>
  </p>
 </form>
 <script>
  var TestController = {
   data: {
    name: &#39;xiaoming&#39;,
    age: 3,
    desc: function() {
            return this.name + &#39; likes looking little movie. he should take care of his body&#39; 
    }
   },
   format: function(val) {
    return val + &#39;岁&#39;
   },
   update: function() {
    this.name = &#39;this is a test&#39;
    this.age = 18
   }
  }
  $(&#39;body&#39;).controller()
 </script>

First define a controller, which can be a json object or a function, and then define data-context="[controller name]" in the top-level element to bind the controller to All elements under this node. If there is a nested Controller in the descendants of the element, the scope of the child elements below the element it is located in points to the child controller.

1. Monitoring attributes and complex attributes

All attributes must be defined under the data node. If the attributes inside are defined as functions, they are considered complex attributes (such as desc) , complex attributes are read-only, and an error will be prompted if they are reassigned.

The format bound to the html element: "{attribute name,fomat=[controller method]}", the attribute name supports nested attributes, such as (a.b); the attribute name does not support expressions, consider If you feel it is not necessary, you can use complex attributes instead. The current disadvantage is that if the business is complex, a large number of complex attributes may be generated; on the right side of the attribute name are optional parameters. Currently, there is only format, which is the conversion method for attributes to be displayed on HTML.

2. Instruction

The binding instruction syntax is in the form of bind-{instruction}. Currently, only val, attr, text, html, and template are implemented. In fact, it can It can be seen that the first four simply encapsulate the jqeury method. The template is implemented using the jquery-tmpl plug-in. If you need more instructions, you can extend it yourself. You only need to implement the init initial loading method (receive the current observer parameter), and the update method (parameter description: corresponding jquery element, latest value, current controller instance); if you are extending an existing instruction, the original one will be overwritten by default. As follows:

$.controller.addDirective("val", {
  init: function (observer) {
   if (observer.$ele.is(&#39;input,select&#39;)) {
    //监听onchange事件
    observer.$ele.on(&#39;input propertychange&#39;, function () {
     var newVal = $(this).val()
     observer.writeValue(newVal)
    })
   }
  },
  update: function ($ele, newVal, controller) {
   $ele.val && $ele.val(newVal)
  }
 })

3. Event

Bind event syntax: on-{event}="{controller method},type=on/one", control On the right side of the controller method are optional parameters. Currently, there are only binding types on/one, and the default is on; the controller method receives two parameters, one is the initial parameter that can be set on the element corresponding to the event, and the other is the event event parameter;

<button type="button" class="btn btn-primary" data-page="1" on-click="refesh">查询</button>

4. Method

Use this.property name directly to directly access the properties under the corresponding data node.

5. Hooks

init and created. Init is after monitoring all attributes and before compiling the dom. You can initialize parameters on this method; created is after compiling the dom elements. .

The controller implements the extend inheritance method by default, which can inherit another controller and must be used in the init method. Currently you can also use prototypal inheritance to implement it yourself.

init: function () {
    this.extend(PageController)
   },
   created: function () {
    //TODO
   },

6. Extension

I believe that everyone will definitely have a set of common components when doing projects, then they can be extended as follows, and the corresponding components are mounted by default Go to all the controller examples and call them directly under the corresponding method: this.http.post();

But there is a suggestion, which is to try to uniformly point the scope of the callback method to Controller, so that scope problems will not always occur during development.

$.controller.extend({
   utils: utils,
   notify: $.notify,
   modal: $.modal,
   http: $.http,
   alert: $.alert
  })

7. Principles and code analysis (to be continued...)

The entire js code is only more than 300 lines, so the implementation is relatively simple and has many aspects It has not been taken into account. There are also some functions that I want to implement but have not done. Currently, array change detection and local update of related DOM are not supported.

The above is what I compiled for everyone. I hope it will be helpful to everyone in the future.

Related articles:

Details on using axios to solve http request problems in vue2 (detailed tutorial)

In vue Handle the problem of passing parameters in post requests through axios (detailed tutorial)

Add axios components through vue to solve the problem of null parameters in post (detailed tutorial)

Sending a post request through axios found that springMVC could not receive parameters (detailed tutorial)

Using the xe-utils function library in vue (detailed tutorial)

jQuery koa2 Example of implementing a simple Ajax request

The above is the detailed content of Implementing the MVVM framework in js (detailed tutorial). For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn