Cette fois, je vais vous apporter une explication détaillée de l'utilisation du modèle éditeur-abonné js. Quelles sont les précautions lors de l'utilisation du modèle éditeur-abonné js. Ce qui suit est un cas pratique, allons-y. jetez un oeil.
Le modèle éditeur-abonné est un modèle très courant, tel que :
1. Acheter et vendre une maison
Lors de l'achat ou de la vente d'une maison en viager, les intermédiaires forment un modèle de publication-abonné. Les personnes qui achètent une maison ont généralement besoin d'informations telles que la disponibilité du logement, le prix, la surface utilisable, etc. Il joue le rôle d'un abonné
L'intermédiaire obtient les informations sur la maison du vendeur et en informe l'acheteur en fonction des coordonnées client qu'il a en main (le numéro de téléphone portable de la personne qui achète la maison). Il agit en tant qu'éditeur
. Si le vendeur souhaite vendre sa maison, il doit en informer l'agent et lui remettre les informations pour qu'il les libère
2. Les utilisateurs qui s'abonnent aux informations du site
Rôle d'abonné : Internautes qui ont besoin de s'abonner à certains types d'informations, comme par exemple des articles de type javascript
sur un site internet Rôle d'éditeur : serveur de boîtes aux lettres, informe les utilisateurs en fonction des boîtes aux lettres d'abonnement des utilisateurs collectées par le site Web
. Si le propriétaire du site Web souhaite informer les abonnés, il doit indiquer au serveur de messagerie le contenu pertinent de l'article à envoyer
Il y a tellement d’exemples, je ne vais pas tous les énumérer
Cet article utilise l'abonnement au site Web pour dériver le cadre éditeur-abonné, puis utilise le cadre éditeur-abonné pour reconstruire un simple panier d'achat
var Site = {}; Site.userList = []; Site.subscribe = function( fn ){ this.userList.push( fn ); } Site.publish = function(){ for( var i = 0, len = this.userList.length; i < len; i++ ){ this.userList[i].apply( this, arguments ); } } Site.subscribe( function( type ){ console.log( "网站发布了" + type + "内容" ); }); Site.subscribe( function( type ){ console.log( "网站发布了" + type + "内容" ); }); Site.publish( 'javascript' ); Site.publish( 'html5' );
Site.userList est utilisé pour enregistrer les abonnés
Site.subscribe est un abonné spécifique. Les informations spécifiques souscrites par chaque abonné sont enregistrées dans Site.userList
. Site.publish est l'éditeur : selon la liste d'utilisateurs enregistrée, parcourez (notifiez) un par un et exécutez la logique métier à l'intérieur de
Mais ce modèle d'abonné publié a un problème. Il ne peut pas s'abonner au type souhaité. Dans l'exemple ci-dessus, j'ai ajouté 2 abonnés (ligne 11, ligne 14). Tant que le site Web envoie des informations, tous les messages peuvent être reçus. mais certains utilisateurs peuvent vouloir uniquement recevoir du javascript ou du html5, donc ensuite, nous devons continuer à nous améliorer, en espérant recevoir des informations spécifiques si ce n'est pas le type d'abonnement de quelqu'un, nous ne les recevrons pas
var Site = {}; Site.userList = {}; Site.subscribe = function (key, fn) { if (!this.userList[key]) { this.userList[key] = []; } this.userList[key].push(fn); } Site.publish = function () { var key = Array.prototype.shift.apply(arguments), fns = this.userList[key]; if ( !fns || fns.length === 0) { console.log( '没有人订阅' + key + "这个分类的文章" ); return false; } for (var i = 0, len = fns.length; i < len; i++) { fns[i].apply(this, arguments); } } Site.subscribe( "javascript", function( title ){ console.log( title ); }); Site.subscribe( "es6", function( title ){ console.log( title ); }); Site.publish( "javascript", "[js高手之路]寄生组合式继承的优势" ); Site.publish( "es6", "[js高手之路]es6系列教程 - var, let, const详解" ); Site.publish( "html5", "html5新的语义化标签" );
var Event = { userList : {}, subscribe : function (key, fn) { if (!this.userList[key]) { this.userList[key] = []; } this.userList[key].push(fn); }, publish : function () { var key = Array.prototype.shift.apply(arguments), fns = this.userList[key]; if (!fns || fns.length === 0) { console.log('没有人订阅' + key + "这个分类的文章"); return false; } for (var i = 0, len = fns.length; i < len; i++) { fns[i].apply(this, arguments); } } }; var extend = function( dstObj, srcObj ){ for( var key in srcObj ){ dstObj[key] = srcObj[key]; } } var Site = {}; extend( Site, Event ); Site.subscribe( "javascript", function( title ){ console.log( title ); }); Site.subscribe( "es6", function( title ){ console.log( title ); }); Site.publish( "javascript", "寄生组合式继承的优势" ); Site.publish( "es6", "es6系列教程 - var, let, const详解" ); Site.publish( "html5", "html5新的语义化标签" );
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="js/cart.js"></script> </head> <body> <p id="box"> <ul> <li> <input type="button" value="-"> <span class="num">0</span> <input type="button" value="+"> <span>单价:</span> <span class="unit">15元;</span> <span class="label">小计:</span> <span class="subtotal">0</span>元 </li> <li> <input type="button" value="-"> <span class="num">0</span> <input type="button" value="+"> <span>单价:</span> <span class="unit">10元;</span> <span class="label">小计:</span> <span class="subtotal">0</span>元 </li> <li> <input type="button" value="-"> <span class="num">0</span> <input type="button" value="+"> <span>单价:</span> <span class="unit">5元;</span> <span class="label">小计:</span> <span class="subtotal">0</span>元 </li> <li> <input type="button" value="-"> <span class="num">0</span> <input type="button" value="+"> <span>单价:</span> <span class="unit">2元;</span> <span class="label">小计:</span> <span class="subtotal">0</span>元 </li> <li> <input type="button" value="-"> <span class="num">0</span> <input type="button" value="+"> <span>单价:</span> <span class="unit">1元;</span> <span class="label">小计:</span> <span class="subtotal">0</span>元 </li> </ul> <p class="total-box"> 商品一共 <span id="goods-num">0</span> 件; 一共花费 <span id="total-price">0</span> 元; 其中最贵的商品单价是<span id="unit-price">0</span>元 </p> </p> </body> </html>
function getByClass(cName, obj) { var o = null; if (arguments.length == 2) { o = obj; } else { o = document; } var allNode = o.getElementsByTagName("*"); var aNode = []; for( var i = 0 ; i < allNode.length; i++ ){ if( allNode[i].className == cName ){ aNode.push( allNode[i] ); } } return aNode; } function getSubTotal( unitPrice, goodsNum ){ return unitPrice * goodsNum; } function getSum(){ //计算总花费 var aSubtotal = getByClass("subtotal"); var res = 0; for( var i = 0; i < aSubtotal.length; i++ ){ res += parseInt(aSubtotal[i].innerHTML); } return res; } function compareUnit() { //比单价,找出最高的单价 var aNum = getByClass( "num"); var aUnit = getByClass( "unit"); var temp = 0; for( var i = 0; i < aNum.length; i++ ){ if( parseInt(aNum[i].innerHTML) != 0 ){ if( temp < parseInt(aUnit[i].innerHTML) ) { temp = parseInt(aUnit[i].innerHTML); } } } return temp; } window.onload = function () { var aInput = document.getElementsByTagName("input"); var total = 0; var oGoodsNum = document.getElementById("goods-num"); var oTotalPrice = document.getElementById("total-price"); var oUnitPrice = document.getElementById("unit-price"); for (var i = 0; i < aInput.length; i++) { if (i % 2 != 0) { //加号 aInput[i].onclick = function () { //当前加号所在行的数量 var aNum = getByClass( "num", this.parentNode ); var n = parseInt( aNum[0].innerHTML ); n++; aNum[0].innerHTML = n; //获取单价 var aUnit = getByClass( "unit", this.parentNode ); var unitPrice = parseInt(aUnit[0].innerHTML); var subtotal = getSubTotal( unitPrice, n ); var aSubtotal = getByClass( "subtotal", this.parentNode ); aSubtotal[0].innerHTML = subtotal; total++; //商品总数 oGoodsNum.innerHTML = total; oTotalPrice.innerHTML = getSum(); oUnitPrice.innerHTML = compareUnit(); } }else { aInput[i].onclick = function(){ var aNum = getByClass( "num", this.parentNode ); if ( parseInt( aNum[0].innerHTML ) != 0 ){ var n = parseInt( aNum[0].innerHTML ); n--; aNum[0].innerHTML = n; //获取单价 var aUnit = getByClass( "unit", this.parentNode ); var unitPrice = parseInt(aUnit[0].innerHTML); var subtotal = getSubTotal( unitPrice, n ); var aSubtotal = getByClass( "subtotal", this.parentNode ); aSubtotal[0].innerHTML = subtotal; total--; //商品总数 oGoodsNum.innerHTML = total; oTotalPrice.innerHTML = getSum(); oUnitPrice.innerHTML = compareUnit(); } } } } }
window.onload = function () { var Event = { userList: {}, subscribe: function (key, fn) { if (!this.userList[key]) { this.userList[key] = []; } this.userList[key].push(fn); }, publish: function () { var key = Array.prototype.shift.apply(arguments), fns = this.userList[key]; if (!fns || fns.length === 0) { return false; } for (var i = 0, len = fns.length; i < len; i++) { fns[i].apply(this, arguments); } } }; (function(){ var aBtnMinus = document.querySelectorAll( "#box li>input:first-child"), aBtnPlus = document.querySelectorAll( "#box li>input:nth-of-type(2)"), curNum = 0, curUnitPrice = 0; for( var i = 0, len = aBtnMinus.length; i < len; i++ ){ aBtnMinus[i].index = aBtnPlus[i].index = i; aBtnMinus[i].onclick = function(){ (this.parentNode.children[1].innerHTML > 0) && Event.publish( "total-goods-num-minus" ); --this.parentNode.children[1].innerHTML < 0 && (this.parentNode.children[1].innerHTML = 0); curUnitPrice = this.parentNode.children[4].innerHTML; Event.publish( "minus-num" + this.index, parseInt( curUnitPrice ), parseInt( this.parentNode.children[1].innerHTML ) ); }; aBtnPlus[i].onclick = function(){ (this.parentNode.children[1].innerHTML >= 0) && Event.publish( "total-goods-num-plus" ); this.parentNode.children[1].innerHTML++; curUnitPrice = this.parentNode.children[4].innerHTML; Event.publish( "plus-num" + this.index, parseInt( curUnitPrice ), parseInt( this.parentNode.children[1].innerHTML ) ); } } })(); (function(){ var aSubtotal = document.querySelectorAll("#box .subtotal"), oGoodsNum = document.querySelector("#goods-num"), oTotalPrice = document.querySelector("#total-price"); Event.subscribe( 'total-goods-num-plus', function(){ ++oGoodsNum.innerHTML; }); Event.subscribe( 'total-goods-num-minus', function(){ --oGoodsNum.innerHTML; }); for( let i = 0, len = aSubtotal.length; i < len; i++ ){ Event.subscribe( 'minus-num' + i, function( unitPrice, num ){ aSubtotal[i].innerHTML = unitPrice * num; }); Event.subscribe( 'plus-num' + i, function( unitPrice, num ){ aSubtotal[i].innerHTML = unitPrice * num; }); } })(); console.log( Event.userList ); }
Quelles sont les méthodes de déconstruction es6
Fonctionnement du système de fichiers Node.js
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!