亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 語言 > JavaScript > 正文

自定義Angular指令與jQuery實現的Bootstrap風格數據雙向綁定的單選與多選下拉框

2024-05-06 16:26:08
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了自定義Angular指令與jQuery實現的Bootstrap風格數據雙向綁定的單選與多選下拉框 的相關資料,需要的朋友可以參考下
 

先說點閑話,熟悉Angular的猿們會喜歡這個插件的。

00.本末倒置

不得不承認我是一個喜歡本末倒置的人,學生時代就喜歡先把晚交的作業先做,留著馬上就要交的作業不做,然后慢悠悠做完不重要的作業,臥槽,XX作業馬上要交了,趕緊補補補。如今做這個項目,因為沒找到合適的多選下拉Web插件,又不想用html自帶的丑陋的<select multiple></select>,自己花了一整天時間做了一個?;蛟S這樣占用的主要功能開發的時間,開發起來會更有緊迫感吧。感覺自己是個抖M自虐傾向,并且伴有css和代碼縮進強迫癥的程序猿。

01.畫蛇添足

Angular強大的控制器似乎已經可以滿足大部分UI上的需求了,但是NodeJS應用往往會使用ejs,jade這樣的模板引擎來動態生成html頁面,那么問題來了,當我想把后臺傳給express中res.render()的參數直接顯示到界面而且綁定到相應的ng-model怎么辦?

解決方法1,不要什么事一次來,Angular的Controller發個post請求再拿數據不就行了

解決方法2,先用模板暫存在html上,再讓Controller根據頁面上的數據來初始化$scope的值

解決方法3,鄙人對Angular和EJS才疏學淺,誰有好辦法教我唄

比如現在要做一個選擇下拉框<select>n個<option>xx</option></select>,選項在后臺,我不想單獨發post拿,也不想放在頁面上,Controller單獨寫邏輯處理,而Angular社區有個ui-select插件,看起來數據是從$scope取的,并不是直接拿的<option />標簽的數據,當時我就火了,不就一個下拉框,自己做唄。

10.樂觀的程序猿

思路很明確,定義一個Angular directive -> 把選項值拿出來 -> 各種事件加加加 -> scope數據綁定 -> 完結撒花
我估計的時間是半天,然而實際花了多久只能呵呵了,css強迫癥,Angular理解不深(所以很多html操作還是在用jQuery),事件考慮不全導致了最終花了超過兩倍的時間做完,
不廢話了,簡單實用,既可以即時綁定ng-model $scope.xxx,也可以直接調jQuery的$("標簽的id").val()也能拿到值,
git傳送門duang:https://git.oschina.net/code2life/easy-select.git
demo傳送門duang~duang:http://ydxxwb.sinaapp.com/easy-select-demo/  (代碼不是最新,有兩個fix的bug還沒有部署上去)

11.放碼

1.使用方法: 引入庫文件Bootstrap,Angular1.x,引入style.css文件(可以修改css自定義自己想要的樣式),easy-select.js,定義Angular的Controller,依賴easySelect模塊,像這樣 ↓
angular.module('dataDisplay', ['easySelect']).controller('selectController', ['$scope', '$http',function ($scope, $http) {  // your code }]);

然后參考demo示例的規范定義選擇框就行啦,是不是很有html原生select標簽的親切感

2.源碼解釋:dom操作和事件都是用jQuery實現的,每一步都有簡略的注釋,實現雙向綁定的關鍵在于取得標簽上定義的ng-model,然后在事件中設置scope[ng-model]的值,
并且調用$digest()循環來讓Angular根據ng-model更新DOM,$digest是Angular實現雙向綁定的核心之一,原理是將變化的scope值同步到所有需要更新的地方,實現暫時還不大明白,有空單獨研究一下這些Angular里面$,$$開頭的東西。

3.自適應與css,Bootstrap就是自適應的,css可以自己定制不同的風格,style.css都有相關注釋

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)?"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 ? "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 ? "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.如果看到了這里,說明對這個小東西有興趣,git上一起完善吧,自定義選項模板,選項分組這兩個功能還沒有實現。少年,加入開源的大軍吧。

以上所述是小編給大家分享的自定義Angular指令與jQuery實現的Bootstrap風格數據雙向綁定的單選與多選下拉框,希望大家喜歡。



注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美亚洲国产成人精品| 国产精品成人免费视频| 亚洲成人中文字幕| 日本国产一区二区三区| 91性高湖久久久久久久久_久久99| 久久人人看视频| 久久久久成人精品| 在线精品视频视频中文字幕| 精品亚洲一区二区三区在线观看| 亚洲自拍av在线| 日韩美女视频中文字幕| 欧美激情精品久久久久久| 久久久久久久一区二区三区| 国产精品久久久久久久久久东京| 国产欧美日韩精品丝袜高跟鞋| 色综合色综合久久综合频道88| 久久久精品在线| 亚洲片av在线| 日韩中文字幕网址| 国产一区二区三区在线免费观看| 日韩av在线免费播放| 亚洲欧美国产精品| 热99久久精品| 亚洲成人xxx| 欧美精品免费在线| 国产精品人人做人人爽| 欧美午夜xxx| 日韩一区二区欧美| 精品爽片免费看久久| 欧美精品18videos性欧美| 国产精品96久久久久久又黄又硬| 美女撒尿一区二区三区| 国产精品视频免费在线观看| 久久精品视频免费播放| 日韩专区在线观看| 久久久国产精品视频| 久久av在线看| 狠狠久久五月精品中文字幕| 国产精品激情av在线播放| 色一区av在线| 日韩在线精品视频| 欧美精品久久一区二区| 精品少妇一区二区30p| 久久精品国产一区二区电影| 久久久久久久91| 亚洲精品第一国产综合精品| 欧美大学生性色视频| 91亚洲国产成人久久精品网站| 欧美精品国产精品日韩精品| 日韩在线视频中文字幕| 日韩精品极品在线观看| 亚洲新声在线观看| 国产精品美女主播| 2019日本中文字幕| 日韩激情av在线播放| www.欧美精品一二三区| 成人a在线观看| 国产精品视频不卡| 亚洲精品在线看| 亚洲国产精彩中文乱码av| 777精品视频| 日本成熟性欧美| 久久九九国产精品怡红院| 91免费视频网站| 国产精品成人品| 中文字幕亚洲综合久久筱田步美| 第一福利永久视频精品| 成人444kkkk在线观看| 亚洲精品福利在线| 国产精品扒开腿爽爽爽视频| 欧美极品在线播放| 另类天堂视频在线观看| 亚洲第一福利网| 激情av一区二区| 久久久久久网址| 久久精品成人一区二区三区| 欧美一级在线播放| 亚洲国产高清福利视频| 日韩美女免费线视频| 国内外成人免费激情在线视频| 91成人在线播放| 国产精品高清免费在线观看| 国产专区欧美专区| 亚洲欧洲日产国产网站| 国产精品美女www| 91性高湖久久久久久久久_久久99| 日韩va亚洲va欧洲va国产| 国产亚洲精品久久久久久| 亚洲香蕉成人av网站在线观看| 日韩精品极品在线观看| 久久久久久久国产精品视频| 国色天香2019中文字幕在线观看| 国产精品一区二区av影院萌芽| 亚洲精品美女视频| 中文字幕亚洲字幕| 欧美视频专区一二在线观看| 国产一区二区三区高清在线观看| 俺去亚洲欧洲欧美日韩| 亚洲网在线观看| 中文字幕精品视频| 国产精品a久久久久久| 亚洲国产精品国自产拍av秋霞| 国产精品第二页| 亚洲日韩欧美视频一区| 国产精品中文字幕久久久| 国产成人久久精品| 国产欧美日韩精品专区| 成人国产精品久久久| 一区二区三区美女xx视频| 欧美日韩国产限制| 久久这里只有精品视频首页| 欧美成人国产va精品日本一级| 91久久在线播放| 国产精品自产拍在线观看中文| 国内揄拍国内精品少妇国语| 91美女高潮出水| 亚洲色图校园春色| 日韩欧美成人网| 美女少妇精品视频| 97在线免费观看视频| 欧美诱惑福利视频| 亚洲成色777777女色窝| 欧美成人免费视频| 91网站在线免费观看| 欧美视频专区一二在线观看| www.亚洲男人天堂| 久久这里有精品视频| 伦理中文字幕亚洲| 亚洲一区美女视频在线观看免费| 久久久久久国产免费| 久久久久久久久久久免费精品| 欧美另类极品videosbest最新版本| 日韩成人在线视频观看| 粗暴蹂躏中文一区二区三区| 精品中文字幕在线观看| www.亚洲免费视频| 国产精品久久久久aaaa九色| 成人激情视频免费在线| 欧美老女人性生活| 国产精品吴梦梦| 在线播放日韩专区| 2019中文字幕免费视频| 亚洲成人a**站| 欧美精品激情在线| 成人av.网址在线网站| 国产精品成人v| 亚洲精品乱码久久久久久按摩观| 国产精品久久久久免费a∨| 琪琪亚洲精品午夜在线| 欧美综合在线观看| 国产999精品久久久| 亚洲人成在线电影| 亚洲欧美日韩视频一区| 91精品视频在线免费观看| 国产精品久久久久久久久久东京| 九九久久精品一区| 欧美在线视频导航| 国产a∨精品一区二区三区不卡| 亚洲aa中文字幕| 狠狠色狠狠色综合日日小说| 欧美黑人性生活视频| 日韩在线视频线视频免费网站| 久久久精品视频在线观看| 国产日本欧美一区二区三区在线|