Maison >interface Web >js tutoriel >Liaison bidirectionnelle de données de style Bootstrap de listes déroulantes à sélection unique et à sélection multiple implémentées par les directives Angular personnalisées et jQuery_AngularJS

Liaison bidirectionnelle de données de style Bootstrap de listes déroulantes à sélection unique et à sélection multiple implémentées par les directives Angular personnalisées et jQuery_AngularJS

WBOY
WBOYoriginal
2016-05-16 15:26:141934parcourir

Parlons-en un peu d'abord. Les personnes qui connaissent Angular apprécieront ce plug-in.

00. Mettre la charrue avant les bœufs

Je dois admettre que je suis une personne qui aime mettre la charrue avant les bœufs. Quand j'étais étudiant, j'aimais faire d'abord les devoirs tardifs, laisser les devoirs à rendre bientôt, puis terminer lentement les devoirs sans importance. Bon sang. XX devoirs arrive bientôt, alors dépêche-toi et rattrape-le. Maintenant, je travaille sur ce projet, car je n'ai pas trouvé de plug-in Web déroulant à sélection multiple approprié et je ne voulais pas utiliser le vilain 83e93235161a78387dfc0b11c4aaaabd18bb6ffaf0152bbe49cd8a3620346341 avec HTML, j'ai donc passé une journée entière à en créer un. Peut-être que le temps consacré au développement des fonctions principales de cette manière rendra le développement plus urgent. Je me sens comme un programmeur avec des tendances masochistes et un trouble obsessionnel-compulsif en CSS et en indentation de code.

01. Superflu

Le puissant contrôleur d'Angular semble être capable de répondre à la plupart des besoins de l'interface utilisateur, mais les applications NodeJS utilisent souvent des moteurs de modèles tels que ejs et jade pour générer dynamiquement des pages html. Le problème se pose alors lorsque je veux transmettre l'arrière-plan. Je le fais si les paramètres de res.render() dans express sont directement affichés sur l'interface et liés au modèle ng correspondant ?

Solution 1 : Ne faites pas tout en même temps. Le contrôleur d'Angular peut simplement envoyer une demande de publication, puis obtenir les données
.

Solution 2, utilisez d'abord le modèle pour le stocker temporairement sur le HTML, puis laissez le contrôleur initialiser la valeur de $scope en fonction des données de la page

Solution 3. J'ai peu de connaissances sur Angular et EJS. Quelqu'un peut-il m'apprendre une bonne méthode ?

Par exemple, je souhaite maintenant créer une liste déroulante de sélection 221f08282418e2996498697df914ce4en5a07473c87748fb1bf73f23d45547ab8xx4afa15d3069109ac30911f04c56f333818bb6ffaf0152bbe49cd8a3620346341. Les options sont en arrière-plan. Je ne souhaite pas publier. les séparément, et je ne veux pas non plus les mettre sur la page. Le contrôleur écrit le traitement logique séparément et la communauté Angular dispose d'un plug-in ui-select. Il semble que les données proviennent de $scope, pas directement de <. ;option /> J'étais très populaire à cette époque, pas seulement une liste déroulante, faites-le vous-même.

10. Programmeurs optimistes

L'idée est très claire, définir une directive Angular -> Supprimer la valeur de l'option -> Ajouter divers événements -> J'ai estimé le temps à une demi-journée, mais je ne peux que deviner combien de temps cela a réellement pris. J'ai du CSS obsessionnel-compulsif, une mauvaise compréhension d'Angular (tant d'opérations HTML utilisent encore jQuery) et une prise en compte insuffisante des événements, ce qui a finalement pris plus de deux fois plus de temps. Terminé,
. Plus de bêtises, c'est simple et pratique. Vous pouvez soit lier ng-model $scope.xxx à la volée, soit ajuster directement le $("label's id").val() de jQuery pour obtenir la valeur,
Duang du portail Git :
https://git.oschina.net/code2life/easy-select.git Portail de démonstration duang~duang :
http://ydxxwb.sinaapp.com/easy-select-demo/ (Le code n'est pas le dernier, il y a deux corrections de bugs qui n'ont pas encore été déployées)

11. Notation

1. Comment utiliser : introduisez le fichier de bibliothèque Bootstrap, Angular1.x, introduisez le fichier style.css (vous pouvez modifier le CSS pour personnaliser le style souhaité), easy-select.js, définissez le contrôleur d'Angular et comptez sur le module easySelect Comme ça↓

angulaire.module('dataDisplay', ['easySelect']).controller('selectController', ['$scope', '$http',function ($scope, $http) { // votre code }]);

Ensuite, référez-vous simplement à la spécification de l'exemple de démonstration pour définir la zone de sélection. N'est-il pas très familier avec la balise de sélection HTML native ?


2. Explication du code source : les opérations et les événements DOM sont implémentés avec jQuery, et chaque étape comporte des commentaires simples. La clé pour obtenir une liaison bidirectionnelle est d'obtenir le modèle ng défini sur la balise, puis de définir la portée. dans la valeur event[ng-model],

Et appelez la boucle $digest() pour laisser Angular mettre à jour le DOM selon ng-model. $digest est l'un des cœurs de la liaison bidirectionnelle d'Angular. Le principe est de synchroniser la valeur de portée modifiée à tous les endroits qui doivent l'être. mis à jour. L'implémentation n'est pas encore grande. Je comprends, j'étudierai ces choses en commençant par $, $$ en Angular quand j'aurai le temps.

3. Adaptatif et CSS, Bootstrap est adaptatif, le CSS peut être personnalisé avec différents styles, style.css a des commentaires pertinents

easy-select.js

var comDirective = angular.module('easySelect', []);
comDirective.directive("easySelect", function () {
 return {
  link: function (scope, element, attrs) {
   var ngModel = $(element).attr("ng-model");
   if(!ngModel || ngModel.length == 0) {
    ngModel = "defaultSelectModel";
   }
   var status = false; //toggle boolean
   var valueMap = "";
   var options = $(element).children();
   $(element).attr("style", "padding:0");
   //hide original options
   $.each(options, function (opt) {
    $(options[opt]).attr("style", "display:none");
   });
   //build ul
   var html = "<div id='" + attrs.id + "-root' style='width:100%;position: relative;left:-1px'>" +
    "<p id='display-"+attrs.id + "' style='padding:6px 12px "+ ((attrs.multiple != undefined)&#63;"4px":"7px")+
    " 12px;margin:0;border:none;width:95%;margin-left:2px;background-color: transparent'>" +
    "<span style='display: inline-block;padding-bottom: 3px'> </span></p>" + //this is a dummy span
    "<ul id='" + attrs.id +
    "-container' class='list-group easy-select-container' style='display:none'>"; //options' container
   if(attrs.multiple != undefined) {
    $.each(options, function (opt) {
     html += "<li value='"+ $(options[opt]).val() +"' class='my-li-container list-group-item option-"+
     attrs.id+ "'><div style='width:100%;display:inline-block'>" + $(options[opt]).html() +
     "</div><span value='"+ $(options[opt]).val() +"' class='my-li-option glyphicon glyphicon-ok'></span></li>";
    });
   } else {
    $.each(options, function (opt) {
     if($(options[opt]).attr("default") != undefined) {
      scope[ngModel] = $(options[opt]).val();
      valueMap = $(options[opt]).html();
      html += "<li value='"+ $(options[opt]).val() +"' class='my-li-container list-group-item option-"+ attrs.id+ "'>"
      + $(options[opt]).html() + "</li>";
     } else {
      html += "<li value='"+ $(options[opt]).val() +"' class='my-li-container list-group-item option-"+ attrs.id+ "'>"
      + $(options[opt]).html() + "</li>";
     }
    });
   }
   //if multiple, add button
   if (attrs.multiple != undefined) {
    html += "<li class='list-group-item ' for='ensure-li'><button class='btn btn-default'" +
    " for='ensure-btn' style='padding: 2px' > 确定 </button></li>";
   }
   //render ui
   html += "</ul></div>";
   $(element).append(html);
   $(".my-li-option").each(function(){
    $(this).fadeOut(0);
   });
   if(attrs.multiple == undefined)
    $($("#display-"+attrs.id).children()[0]).html(valueMap);
   //adjust width
   $("#" + attrs.id + "-root").width($("#" + attrs.id + "-root").width() + 2);
   //mouse leave event
   $(element).mouseleave(function(){
    $(".my-li-container").each(function(){
     $(this).attr("style","");
    });
    if(status) {
     $("#" + attrs.id + "-container").attr("style", "display:none");
     status = !status;
    }
   });
   //multiple select seems complex
   if (attrs.multiple != undefined) {
    //click event
    $(element).click(function (e) {
     //if click on tags, remove it
     if($(e.target).attr("for") == "option-tag") {
      // change val and digest change item in angular
      scope[ngModel] = $(element).val().replace($(e.target).attr("value"),"").replace(/;+/,";").replace(/^;/,"");
      $(element).val(scope[ngModel]);
      scope.$digest();
      $(e.target).remove();
      $(".my-li-option").each(function(){
       if($(this).attr("value") == $(e.target).attr("value")) {
        $(this).css("opacity","0.01");
       }
      });
     } else if($(this).attr("for") != 'ensure-li') {
      //toggle ul
      $("#" + attrs.id + "-container").attr("style", status &#63; "display:none" : "");
      status = !status;
     }
    });
    $(".option-"+attrs.id).each(function(){
     $(this).on('click',function(){
      var selectValue = $(element).val();
      var currentValue = $(this).attr("value");
      var selected = false;
      //if option is selected ,remove it
      var temp = selectValue.split(";");
      $.each(temp,function(obj){
       if(temp[obj].indexOf(currentValue) != -1) {
        selected = true;
       }
      })
      if(selected) {
       $($(this).children()[1]).fadeTo(300,0.01);
       scope[ngModel] = $(element).val().replace(currentValue,"").replace(/;{2}/,";").replace(/^;/,"");
       $(element).val(scope[ngModel]);
       scope.$digest();
       $("#display-"+attrs.id + " span").each(function(){
        if($(this).attr("value") == currentValue) {
         $(this).remove();
        }
       });
      } else {
       //add option to val() and ui
       $($(this).children()[1]).fadeTo(300,1);
       scope[ngModel] = ($(element).val()+";"+currentValue).replace(/;{2}/,";").replace(/^;/,"");
       $(element).val(scope[ngModel]);
       scope.$digest();
       $("#display-"+attrs.id).append(
        "<span for='option-tag' value='"+ $(this).attr("value") +"' class='p-option-tag'>"
        +$(this).children()[0].innerHTML+ "</span>");
      }
      status = !status; // prevent bubble
     });
     //control background
     $(this).mouseenter(function(){
      $(".my-li-container").each(function(){
       $(this).attr("style","");
      });
      $(this).attr("style","background-color:#eee");
     });
    });
   } else {
    $(".option-"+attrs.id).each(function(){
     $(this).mouseenter(function(){
      $(".my-li-container").each(function(){
       $(this).attr("style","");
      });
      $(this).attr("style","background-color:#eee");
     });
    });
    //single select ,just add value and remove ul
    $(element).click(function () {
     $("#" + attrs.id + "-container").attr("style", status &#63; "display:none" : "");
     status = !status;
    });
    $(".option-"+attrs.id).each(function(){
     $(this).on('click',function(){
      scope[ngModel] = $(this).attr("value");
      $(element).val(scope[ngModel]);
      scope.$digest();
      console.log(ngModel);
      console.log(element.val());
      $($("#display-"+attrs.id).children()[0]).html($(this).html());
     });
    });
   }
  }
 }
}); 
100. Si vous voyez cela, cela signifie que cette petite chose vous intéresse. Améliorons-le ensemble sur git. Les deux fonctions de personnalisation des modèles d'options et de regroupement d'options n'ont pas encore été implémentées. Jeune homme, rejoignez l’armée de l’open source.


Ce qui précède correspond aux listes déroulantes à sélection unique et à sélection multiple que l'éditeur a partagées avec vous avec des instructions angulaires personnalisées et une liaison bidirectionnelle de données de style Bootstrap implémentées par jQuery.

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn