Avalonjs Implementation Simple Shopping Cart Function of Instance Code

  • 2021-07-18 06:26:04
  • OfStack

First, let's briefly introduce the concept of avalon

avalon is the most powerful MVVM framework in China, and there is no one. Although Taobao KISSY team also made two MVVM frameworks, they all ended in vain. There are few other MVVM frameworks. Only foreigners and idle architects like me have time to delve into this thing. I predicted long ago that MVVM is the ultimate solution for the front end. Before I do grand wireless grand pass on the deep experience, a business logic corresponding to 10 different interfaces, layered architecture is essential. Therefore, bidirectional binding as an antidote, combined with the popular MVC framework, derived the artifact MVVM.

Because we are doing shopping carts recently, and then we use avalon to realize some modules, so let it take its course to realize shopping carts with avalon. At present, it is found that avalon is still relatively powerful, which greatly saves the amount of code.

Shopping cart 1 generally has the functions of adding and subtracting quantity, selecting goods, deleting goods and calculating amount. Because avalon has bidirectional binding function, it eliminates the operation of dom, and only needs to complete the logic of the function, which can be realized in the following steps.

runjs: http://runjs. cn/detail/1dnkgxom

1. Html structure of the page

Here do not consider the good effect, so directly with the simplest html to achieve, mainly including the controller, list cycle, amount display, simple code structure as follows


<body ms-controller="test">
 <ul ms-visible="arr.length">
  <li><input type="checkbox"
 ms-click="checkAll" ms-duplex-checked="checkAllbool"/> All selection </li>
  <li ms-repeat="arr"
 >
  <input type="checkbox"
 ms-attr-value="el.id" ms-duplex="selected" />
  {{el.text}}
  <input type="text"
 name="" ms-attr-value="el.num" ms-on-input="changeNum(el)">
  <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" 
 ms-click="plus(el)"> Plus </a>
  <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" 
 ms-click="minus(el)"> Minus </a>
  <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" 
 ms-click="del(el)"> Delete </a>
  <p> Unit price: {{el.price
 | currency}}</p>
  <p> Amount: {{el.num*el.price
 | currency}}</p>
  </li>
 </ul>
 <p> Total amount: {{total
 | currency}}</p>
 </body>

There are several functional events, such as select all, add and subtract, and delete. The amount uses the filter currency.

2. Introducing avalon. js to define the model

It is necessary to introduce js, so it can be defined after introducing avalon. js


var vm
 = avalon.define({
  $id:
"test"
});

In this way, a simple model is defined. The value of the controller is passed in $id. The controller of this example is written in body. If you don't understand it, you can look at official website.

3. Define the items in the shopping cart

In the actual project, this must be obtained through the background, and it is directly defined here for demonstration. From the structure of html in point 1, it can be seen that the goods in the shopping cart here use arr, so the next definition is arr, which can be defined as follows


arr
 : [
 {
 id:1,
 num:1,
 price:45.5,
 text:' Commodity 1'
 },
 {
 id:2,
 num:1,
 price:8.8,
 text:' Commodity 2'
 }<span
 style="font-size:
 9pt; line-height: 1.5;">]</span>

Here we define two for testing, then we need one value to save the selected commodity id, here we add one selected attribute to the model, the type is array

selected:[]

4. Define the model and method of all selection

Shopping cart inside 1 have the function of all selection, but the form of expression is not 1, so it can be defined as this


checkAllbool
 : false,
checkAll
 : function()
 {
 if (this.checked)
 {
  var _arr
 = [];
  avalon.each(vm.arr,function(index,item){
   _arr[index]
 = item.id+'';
  });
  vm.selected
 = _arr;
 }
else {
  vm.selected=[];
 }
}

The checkAllbool attribute is used to realize and judge whether "Select All" is selected. To select all or unselect all through checkAll is actually to modify the selected attribute in the model. If selected is an empty array, none of them is selected. If that one needs to be selected, only the corresponding values need to be put into the selected array, because checkbox is bound by ms-duplex in html, and the binding is selected attribute.

4. Define the methods of addition, subtraction and deletion

Addition and subtraction are mainly changes in quantity, while deletion is to delete the item directly from arr (previously defined attribute)


plus:
function(el){
 el.num++;
 vm.cal();
 },
minus:
function(el){
 if(el.num>1){
 el.num--;
 vm.cal();
 }
},
del:
function(el){
 vm.arr.remove(el);
},
changeNum:
function(el){
 var _value
 = this.value,
 _reg
 = /^[1-9]\d?$/
 ;
 if(!_reg.test(_value)){
 this.value
 = 1;
 el.num
 = 1;
 }else{
 el.num
 = _value;
 }
 vm.cal();
}

There is also a method to be executed when the input box changes. Here, the operation is carried out by entering and leaving the object. You can look at the html code in Step 1, and you will understand that vm. cal will be executed at the end, whether it is changed or added or subtracted. vm. cal is to calculate the total amount, which will be explained below.

The methods of addition and subtraction are very simple, mainly by modifying the attributes of num, while changeNum adds regular judgment to judge whether the input is a number.

5. Define Calculated Total Amount

The method of calculating the total amount is very simple, that is, multiplying the quantity of all selected goods by the unit price and adding it up, but there is another method involved, that is, finding the corresponding goods through the id of the goods, so as to calculate the amount of the goods.


total:0,
cal:
function(){
 var _arr
 = this.arr,
 _selected
 = this.selected,
 i
 = 0,
 _obj
 = '',
 _prcie
 = 0
 ;
 if(_selected.length){
 for(;i<_selected.length;i++){
  _obj
 = this.findById(_selected[i])
 ||{};
  if(_obj.price
 && _obj.num){
   _prcie
 = _prcie + _obj.price * _obj.num;
  }
 }
 }
 this.total
 = _prcie;
 },
findById:
function(id){
 if(!id)
return '';
 var i=0,
  _arr
 = this.arr,
  _obj
 = '',
  _id
 = parseInt(id,10)
 ;
  for(;i<_arr.length;i++){
  if(_arr[i].id
 === _id){
   _obj
 = _arr[i];
  }
 }
  return _obj;
}

This is mainly used to cycle, find the object of goods and then calculate the amount of goods and then add, the code is slightly longer.

6. Listening Attributes

Two attributes need to be monitored, namely selected and arr. selected is monitored to know whether all products are selected at any time, mainly by monitoring Length. Monitoring arr is to judge whether the goods have been deleted. If length of arr changes, it means that the goods have been deleted and the total amount needs to be recalculated.


vm.selected.$watch("length",
function(n)
 {
 vm.checkAllbool
 = n === vm.arr.size()
 vm.cal();
});
vm.arr.$watch("length",
function(n)
 {
 vm.cal();
});

Through the analysis of the above steps, you can understand the general implementation process, and the following is the complete code.


<!DOCTYPE html> <html>
 <head>
 <title> Shopping cart </title>
 <meta http-equiv="Content-Type"
 content="text/html; charset=UTF-8">
 <meta http-equiv="X-UA-Compatible"
 content="IE=edge" /> 
 <script src="../avalon.js"
 ></script>
 <script>
  var
 vm = avalon.define({
  $id:
 "test",
  arr
 : [
   {
   id:1,
   num:1,
   price:45.5,
   text:' Commodity 1'
   },
   {
   id:2,
   num:1,
   price:8.8,
   text:' Commodity 2'
   }
  ],
  selected
 : ["1"],
  checkAllbool
 : false,
  checkAll
 : function() {
   if
 (this.checked) {
   var
 _arr = [];
   avalon.each(vm.arr,function(index,item){
    _arr[index]
 = item.id+'';
   });
   vm.selected
 = _arr;
   }
 else {
   vm.selected=[];
   }
  },
  plus:
 function(el){
   el.num++;
   vm.cal();
  },
  minus:
 function(el){
   if(el.num>1){
   el.num--;
   vm.cal();
   }
  },
  del:
 function(el){
   vm.arr.remove(el);
  },
  changeNum:
 function(el){
   var
 _value = this.value,
   _reg
 = /^[1-9]\d?$/
   ;
   if(!_reg.test(_value)){
   this.value
 = 1;
   el.num
 = 1;
   }else{
   el.num
 = _value;
   }
   vm.cal();
  },
  total:0,
  cal:
 function(){
   var
 _arr = this.arr,
   _selected
 = this.selected,
   i
 = 0,
   _obj
 = '',
   _prcie
 = 0
   ;
   if(_selected.length){
   for(;i<_selected.length;i++){
    _obj
 = this.findById(_selected[i]) ||{};
    if(_obj.price
 && _obj.num){
    _prcie
 = _prcie + _obj.price * _obj.num;
    }
   }
   }
   this.total
 = _prcie;
   },
  findById:
 function(id){
   if(!id)
 return '';
   var
 i=0,
   _arr
 = this.arr,
   _obj
 = '',
   _id
 = parseInt(id,10)
   ;
   for(;i<_arr.length;i++){
   if(_arr[i].id
 === _id){
    _obj
 = _arr[i];
   }
   }
   return
 _obj;
  }
  });
  vm.selected.$watch("length",
 function(n) {
  vm.checkAllbool
 = n === vm.arr.size()
  vm.cal();
  });
  vm.arr.$watch("length",
 function(n) {
  vm.cal();
  });
  vm.cal();
 </script>
 </head>
 <body ms-controller="test">
 <ul ms-visible="arr.length">
  <li><input type="checkbox"
 ms-click="checkAll" ms-duplex-checked="checkAllbool"/> All selection </li>
  <li ms-repeat="arr"
 >
  <input type="checkbox"
 ms-attr-value="el.id" ms-duplex="selected" />
  {{el.text}}
  <input type="text"
 name="" ms-attr-value="el.num" ms-on-input="changeNum(el)">
  <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" 
 ms-click="plus(el)"> Plus </a>
  <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" 
 ms-click="minus(el)"> Minus </a>
  <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" 
 ms-click="del(el)"> Delete </a>
  <p> Unit price: {{el.price
 | currency}}</p>
  <p> Amount: {{el.num*el.price
 | currency}}</p>
  </li>
 </ul>
 <p> Total amount: {{total
 | currency}}</p>
 </body>
</html>

It's not long since I used avalon. I hope I can have a deeper understanding of mvvm framework and apply more scenes in the future.


Related articles: