前言

除了 AngularJS 内置的指令外,我们还可以创建自定义指令。
通过 .directive() 函数来添加自定义的指令。
调用自定义指令时,需要在HTMl 元素上添加自定义指令名
自定义指令命名规则:使用驼峰命名法来命名,即除第一个单词外的首字母需大写。如: myDirective。
在html页面调用该指令时需要以 - 分割,如: my-directive。示例代码:

<body ng-app="myApp"><my-directive></my-directive><script>var app = angular.module("myApp", []);app.directive("myDirective", function() {return {template : "<h1>模板:可以写自己的html页面代码</h1>"};});
</script></body>

html页面调用自定义指令的四种方式

通过在自定义指令里添加 restrict 属性,根据设置不同的值来决定html页面的调用方式,如:

var app = angular.module("myApp", []);
app.directive("myDirective", function() {return {restrict : "A",//只能通过属性调用template : "<h1>自定义指令!</h1>"};
});

restrict值的不同,决定了调用方式的不同

属性值 调用方式 示例
A (Attribute首字母) 属性名 <div my-directive></div>
C (Class 首字母) 类名 <div class='my-directive'></div>
E (Element 首字母) 元素名 <my-directive></my-directive>
M 注释 <!-- 指令: my-directive>

restrict 默认值为 EA, 即在html页面可通过元素名和属性名来调用自定义指令。

自定义指令属性详解

属性 值类型 说明
restrict string 指令的调用方式,A、C、E、M
priority number 指令执行的优先级
template string 指令使用的模板,可将html页面代码写于此。只能与templateUrl二选其一
templateUrl string 从指定的url地址加载模板。只能与template二选其一
replace boolean 是否用模板替换当前元素。true : 将指令标签替换成temple中定义的内容,页面上不会再有<my-directive>标签;false :则append(追加)在当前元素上,即模板的内容包在<my-directive>标签内部。默认false。
transclude boolean 是否将当前元素的内容转移到模板中
scope boolean /object 指定指令的作用域。false(默认值): 使用父作用域作为自己的作用域(每个引用自定义指令的标签若其中一个标签改变某一变量值,则会影响其他标签的值 )。true: 新建一个作用域,该作用域继承父作用域(两个引用自定义指令的标签之间的变量互不影响)。JavaScript对象:与父作用域隔离,并指定可以从父作用域访问的变量
controller function 定义与其他指令进行交互的接口函数
require string 指定需要依赖的其他指令
link function 以编程的方式操作DOM,包括添加监听器等
compile function 编程的方式修改DOM模板的副本,可以返回链接函数

对表格里的知识进行延伸

1.templateUrl

如果template里拼写的html页面代码十分的多页复杂,拼字符串的话就太麻烦啦,这里我们就可以选择templateUrl。我们可以将要拼写的html页面代码独立到一个页面里,如template.html;然后再指定该html文件所在的路径即可,如templateUrl:”template.html”。用到该自定义指令时,会自动发一个http请求来获取template.html对应的模板内容。这样做的缺点是,多了一个http请求。别急,可以改进的:
angularJS规定了模板还可以用<Script>标签定义:

<script type="text/ng-template" id="template.html"><div>自定义指令模板用Script标签定义的方式,须放在html页面ng-controller指令所在标签的内部</div>
</script>

上面代码写在html页面的ng-controller指令所在标签的里面,这样就不用再去请求它了。示例:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
</head>
<body ><div ng-app="myApp" ng-controller="myController"><!-- 引用自定义指令 --><my-directive></my-directive><!-- 模板代码:须放在myController所在标签内部 --><script type="text/ng-template" id="template.html"><div> 自定义指令模板的templateUrl形式</div></script></div><script>//创建模块var app = angular.module('myApp', []);//创建控制器app.controller('myController', function($scope) { });//创建自定义指令app.directive("myDirective", function() {return {restrict:'E',templateUrl : "template.html"};});</script>
</body></html>

有多个模板时,我们可以将所有的模板集中在一个文件中,只需加载一次,然后根据id的不同调用不同的模板。

2.transclude

定义是否将当前元素(html页面的自定义指令)的内容转移到模板中。
模板中要接收当前元素内容的标签需要使用ng-transclude指令。

<body ><div ng-app="myApp" ng-controller="myController"><!-- 引用自定义指令 --><my-directive>自定义指定令内容</my-directive><!-- 模板代码 --><script type="text/ng-template" id="template.html"><div> 模板内容</div><div ng-transclude></div>//模板接收上面自定义指令间的内容</script></div><script>//创建模块var app = angular.module('myApp', []);//创建控制器app.controller('myController', function($scope) {  });//创建自定义指令app.directive("myDirective", function() {return {templateUrl : "template.html",transclude : true//转移到模板中};});</script>
</body>

3.什么是scope的父作用域

引用自定义指令的html页面的控制器所能控制的范围。下面代码的父作用域就是myController所控制的范围

<body ><div ng-app="myApp" ng-controller="myController">       <my-directive></my-directive><!-- 引用自定义指令 --></div><script>//创建模块var app = angular.module('myApp', []);//创建控制器app.controller('myController', function($scope){ });//创建自定义指令app.directive("myDirective", function() {return {template : "<h1>自定义指令!</h1>"};});</script>
</body>

4.scope属性的值是对象(object)时的用法

AngularJS内置指令的用法:ng-model=”obj”,通过obj这个变量双向绑定值,controller里变了,html页面也跟着变化。这说明,内置指令不仅可作为属性,还可动态改变值,这个要是不懂的,看看基础语法。如下代码:

<div ng-app="myApp" ng-controller="myController">要动态变化的内容: <input ng-model="obj">
</div><script>var app = angular.module('myApp', []);app.controller('myController', function($scope) {$scope.obj = "这个字符串值会同步到html里";});
</script>

自定义指令当然也需要实现这种功能啦。scope属性为对象时,可为自定义指令指定一个可以绑定值的属性。这里还得说明一下的是,这个scope属性与自定义指令里link属性里的scope参数是一个变量。

<!-- =符号的用法-->
<body ><div ng-app="myApp" ng-controller="myController"><!-- 引用自定义指令:obj变量与控制器里的objc变量双向绑定了值 --><my-directive speak="obj"></my-directive></div><script>//创建模块var app = angular.module('myApp', []);//创建控制器app.controller('myController', function($scope) { $scope.obj="父作用域";//父作用域给自定义指令属性赋的值});//创建自定义指令app.directive("myDirective", function() {return {template : "<p>模板内容</p>",scope:{title:"=speak"//定义一个speak属性供html页面的自定义指令用。如果写成title:"="格式,则自定义指令里的属性名就是title。},link: function postLink(scope, iElement, iAttrs) {console.log(scope.title)//这里打印的值与控制器里的值一样}};});</script>
</body>

有了前面的一个示例,下面再来说说绑定策略:即用符号前缀给自定义指令传值。它是一个键值对,键是在自定义指令中使用的,值里符号后面的字符串是html页面自定义指令的属性名;如果值里只有符号,则html页面自定义指令的属性名就是键名。

符号 说明 示例
@ 值传递,单向绑定。html页面自定义指令里的val属性的值可传给link的scope使用。第一种写法——str : “@”,这种写法html页面的指令属性名为str str : “@val”,属性名为val
= 双向绑定数据到指令的属性中,数据值可以是任意类型的。第一种写法:name : “=”,这种写法html页面的自定义指令属性名就是name name : “=username”,属性名是username
& 使用父作用域中的一个函数,可以在指令中调用。第一种写法:getName:”&”,这种写法html页面的自定义指令属性名就是gegName getName : “&getUserName”,属性名是getUserName

其余两种符号用法:

<!-- @符号的用法 -->
<body ><div ng-app="myApp" ng-controller="myController"><!-- 引用自定义指令 --><my-directive title="obj" str="abcd">自定义指定令的内容555</my-directive></div><script>//创建模块var app = angular.module('myApp', []);//创建控制器app.controller('myController', function($scope) { $scope.obj="父作用域";//父作用域给自定义指令属性赋的值});//创建自定义指令app.directive("myDirective", function() {return {template : "<p >模板内容</p>",scope:{title:"=",str:"@"},link: function postLink(scope, iElement, iAttrs) {console.log(scope.str)console.log(scope.title)}};});</script>
</body>
<!-- &符号的用法 -->
<body ><div ng-app="myApp" ng-controller="myController"><!-- 引用自定义指令 --><my-directive fun="test()"></my-directive></div><script>//创建模块var app = angular.module('myApp', []);//创建控制器app.controller('myController', function($scope) { $scope.test = function(){console.log('自定义指令会调用该法,所以这句话会打印到控制台上')}});//创建自定义指令app.directive("myDirective", function() {return {template : "<p >模板内容</p>",scope:{fun:"&"//属性名直接是fun},link: function postLink(scope, iElement, iAttrs) {scope.fun();//调用父作用域的方法,好似不能传参,未深究。}};});</script>
</body>

5.controller属性

controller属性用于提供对外的接口,即该自定义指令会被其他自定义指令调用。所谓的接口,就是this后的变量或方法。
controller可以使用的参数,作用域、节点、节点的属性、节点内容的迁移,这些都可以通过依赖注入被传进来,所以你可以根据需要只写要用的参数,有$scope,Z$element, $attrs, $transclude
调用该自定义指令的指令需要放在该指令之间。假定firstDirective指令是要被调用的自定义指令,expander是调用者指令。如下:

<first-directive><expander ng-repeat="item in list" attribute="list">{{item.title}}:{{item.text}}</expander></first-directive>

既然firstDirective内部还有指令,则firstDirective必须配置transclude属性为true。代码如下:

//用于被调用的自定义指令app.directive('firstDirective',function(){return {template : '<div ng-transclude></div>',replace : true,transclude : true,controller :function(){this.getData = function(val){var data = 3 * val;return data;}this.a  = "abc";}}});

调用其他指令的自定义指令必须配置require属性指定指令名。然后在link函数里就可注入要调用的指令。

//自定义指令app.directive('expander',function(){return {templateUrl : 'template.html',replace : true,transclude : true,require : '^?firstDirective',//引用其他自定义指令,^表示从父节点开始找,?表示将告诉$compile服务,如果所需的指令没找到,不要抛出异常scope : {title : '=attribute'},link : function(scope,element,attris,firstDirct){//注入console.log(firstDirct.a)//调用其他指令的变量console.log(firstDirct.getData(6)) //调用其他指令的方法             }};});

6.link属性用法

link后的方法在指令中负责执行DOM 操作和注册事件监听器等。link函数有五个参数(scope,element,attrs,controller,linker)。link 方法的参数解释:
scope: 它与自定义指令里的scope属性是一个东西。它是指令scope的引用,所以可改名为sco等其他名字。scope 变量在初始化时是不被定义的,link 方法会注册监视器监视值变化事件。
element: 包含指令的DOM元素的引用, link 方法一般通过jQuery 操作实例(如果没有加载jQuery,还可以使用Angular’s jqLite )。
controller: 在有嵌套指令的情况下使用。这个参数作用在于把子指令的引用提供给父指令,允许指令之间进行交互,如前面的例子。
注意:当调用link 方法时, 通过值传递(”@”)的scope 变量将不会被初始化,它们将会在指令的生命周期中另一个时间点进行初始化,如果你需要监听这个事件,可以使用scope.$watch 方法。

7.link与compile的区别

compile函数有三个参数(cElement,cAttrs,cLinker),使用compile函数可以在ng创建原始dom实例以及创建scope实例之前,改变原始的dom(template element);可以应用于当需要生成多个element实例但只有一个template element的情况,ng-repeat就是一个最好的例子。它就在是compile函数阶段改变原始的dom生成多个原始dom节点,然后每个又生成element实例。因为compile只会运行一次,所以当你需要生成多个element实例的时候是可以提高性能的。
link函数有五个参数(scope,element,attrs,ctrl,linker)。
link又分为pre-link和post-link,在代码里直接用pre和post表示,当我们直接使用link时,默认跟post一样。我在网上找了个例子来说明一下区别,代码如下:

<body><div ng-app="myApp" ng-controller="myController"><level-one><level-two><level-three> Hello </level-three></level-two></level-one></div><script>//创建模块var app = angular.module('myApp', []);//创建控制器app.controller('myController', function($scope) { });//自定义指令function createDirective(name){return function(){return {restrict: 'E',compile: function(tElem, tAttrs){console.log(name + ': compile => ' + tElem.html());return {pre: function(scope, iElem, iAttrs){console.log(name + ': pre link => ' + iElem.html());},post: function(scope, iElem, iAttrs){console.log(name + ': post link => ' + iElem.html());}}}}}}app.directive('levelOne', createDirective('levelOne'));app.directive('levelTwo', createDirective('levelTwo'));app.directive('levelThree', createDirective('levelThree'));</script>
</body>

注意打印结果:

levelOne: compile => <level-two><level-three>Hello </level-three></level-two>levelTwo: compile => <level-three>Hello </level-three>levelThree: compile => Hello levelOne: pre link => <level-two><level-three>Hello </level-three></level-two>levelTwo: pre link => <level-three>Hello </level-three>levelThree: pre link => Hello levelThree: post link => Hello
levelTwo: post link => <level-three>Hello </level-three>levelOne: post link => <level-two><level-three>Hello </level-three></level-two>

分析打印结果
运行levelone指令中的compile函数,ng就会递归遍历它的dom节点,然后在level-two与level-three上面重复这些操作。所以会依次打印连续三个compile。
pre会在所有compile执行完后且在所有post之前执行。这样可以在执行post前执行一些其他代码,有些类似AOP。
由上面结果可知,post的执行顺序却是先levelthree最后levelone,即反向调用相关联的post-link函数。这么做的好处是,当我们运行levelone时,保证leveltwo与levelthree都已经执行过了,这样就会更安全。所以默认的link就是post。

一个我做过的分页例子

之所以展示这个代码,主要是给一些朋友看看真实的项目,,多余的东西删掉了,具体的注入这里就不在讲了。
html页面代码:

<div class="wp-20" ng-controller="AppStatisticController" ng-cloak><div class="panel-footer"><s-pagination conf="paginationConf"></s-pagination></div>
</div>

控制器代码:

"use strict";//严格define(["application-configuration", "s-pagination", "tableDataService"], function (app) {app.register.controller("AppStatisticController", ["$scope", "$rootScope", "$stateParams","$http", "tableDataService",function($scope, $rootScope, $stateParams, $http, tableDataService) {        var getTableDataSuccess = function(result) {if(result.c == 1) {$scope.title = result.title;$scope.lists = result.pageList;$scope.total = result.data;$scope.paginationConf.totalItems = result.total;}else if(result.c == 2){//弹出框,没有查到数据 } else {alert(result.i);}};var getTableDataError = function(result) {alert(result);};/*重要的代码,这个paginationConf与自定义指令双向绑定数据*/$scope.paginationConf = {currentPage: 1,itemsPerPage: 10,pagesLength: 9,search: false,onChange: function() {var param = {"pageNo": this.currentPage,"pageSize": this.itemsPerPage,"timeType": $scope.formData.timeType,"adStyle":$scope.formData.adStyle,};param.appId = $stateParams.appId;tableDataService.getTableData(param,"ims/appStat.do",getTableDataSuccess,getTableDataError);}};$scope.$watch("formData",function(newValue,oldValue, scope) {if(newValue.keywords == oldValue.keywords) {$scope.paginationConf.search = true;}}, true);}]);
});

自定义指令代码:也算是angularJS的分页插件

/*** 分页插件封装s-pagination.js* @date 2016-05-06* @author Peter*/angular.module('s.pagination', []).directive('sPagination',[function(){//自定义指令return {restrict: 'E',//仅限元素名调用template: '<div class="page-list">' +'<ul class="pagination" ng-show="conf.totalItems > 0">' +'<li ng-class="{disabled: conf.currentPage == 1}" ng-click="prevPage()"><span>&laquo;</span></li>' +'<li ng-repeat="item in pageList track by $index" ng-class="{active: item == conf.currentPage, separate: item == \'...\'}" ' +'ng-click="changeCurrentPage(item)">' +'<span>{{ item }}</span>' +'</li>' +'<li ng-class="{disabled: conf.currentPage == conf.numberOfPages}" ng-click="nextPage()"><span>&raquo;</span></li>' +'</ul>' +'<div class="page-total" ng-show="conf.totalItems > 0">' +'第<input type="text" ng-model="jumpPageNum"  ng-keyup="jumpToPage($event)"/>页 ' +'每页<select ng-model="conf.itemsPerPage" ng-options="option for option in conf.perPageOptions "></select>' +'/共<strong>{{ conf.totalItems }}</strong>条' +'</div>' +'<div class="no-items" ng-show="conf.totalItems <= 0">暂无数据</div>' +'</div>',replace: true,scope: {conf: '='//双向绑定数据},link: function(scope, element, attrs){// 变更当前页scope.changeCurrentPage = function(item) {if(item == '...'){return;}else{scope.conf.currentPage = item;}};// 定义分页的长度必须为奇数 (default:5)scope.conf.pagesLength = parseInt(scope.conf.pagesLength) ? parseInt(scope.conf.pagesLength) : 5 ;if(scope.conf.pagesLength % 2 === 0){// 如果不是奇数的时候处理一下scope.conf.pagesLength = scope.conf.pagesLength -1;}// conf.erPageOptionsif(!scope.conf.perPageOptions){scope.conf.perPageOptions = [10, 20, 30, 40, 50];}// pageList数组function getPagination(newValue, oldValue) {//新增属性search   用于附加搜索条件改变时触发if(newValue[1] != oldValue[1] || newValue[2] != oldValue[2]) {scope.conf.search = true;}// conf.currentPagescope.conf.currentPage = parseInt(scope.conf.currentPage) ? parseInt(scope.conf.currentPage) : 1;// conf.totalItemsscope.conf.totalItems = parseInt(scope.conf.totalItems) ? parseInt(scope.conf.totalItems) : 0;// conf.itemsPerPage (default:15)scope.conf.itemsPerPage = parseInt(scope.conf.itemsPerPage) ? parseInt(scope.conf.itemsPerPage) : 15;// numberOfPagesscope.conf.numberOfPages = Math.ceil(scope.conf.totalItems/scope.conf.itemsPerPage);// judge currentPage > scope.numberOfPagesif(scope.conf.currentPage < 1){scope.conf.currentPage = 1;}// 如果分页总数>0,并且当前页大于分页总数if(scope.conf.numberOfPages > 0 && scope.conf.currentPage > scope.conf.numberOfPages){scope.conf.currentPage = scope.conf.numberOfPages;}// jumpPageNumscope.jumpPageNum = scope.conf.currentPage;// 如果itemsPerPage在不在perPageOptions数组中,就把itemsPerPage加入这个数组中var perPageOptionsLength = scope.conf.perPageOptions.length;// 定义状态var perPageOptionsStatus;for(var i = 0; i < perPageOptionsLength; i++){if(scope.conf.perPageOptions[i] == scope.conf.itemsPerPage){perPageOptionsStatus = true;}}// 如果itemsPerPage在不在perPageOptions数组中,就把itemsPerPage加入这个数组中if(!perPageOptionsStatus){scope.conf.perPageOptions.push(scope.conf.itemsPerPage);}// 对选项进行sortscope.conf.perPageOptions.sort(function(a, b){return a-b});scope.pageList = [];if(scope.conf.numberOfPages <= scope.conf.pagesLength){// 判断总页数如果小于等于分页的长度,若小于则直接显示for(i =1; i <= scope.conf.numberOfPages; i++){scope.pageList.push(i);}}else{// 总页数大于分页长度(此时分为三种情况:1.左边没有...2.右边没有...3.左右都有...)// 计算中心偏移量var offset = (scope.conf.pagesLength - 1)/2;if(scope.conf.currentPage <= offset){// 左边没有...for(i =1; i <= offset +1; i++){scope.pageList.push(i);}scope.pageList.push('...');scope.pageList.push(scope.conf.numberOfPages);}else if(scope.conf.currentPage > scope.conf.numberOfPages - offset){scope.pageList.push(1);scope.pageList.push('...');for(i = offset + 1; i >= 1; i--){scope.pageList.push(scope.conf.numberOfPages - i);}scope.pageList.push(scope.conf.numberOfPages);}else{// 最后一种情况,两边都有...scope.pageList.push(1);scope.pageList.push('...');for(i = Math.ceil(offset/2) ; i >= 1; i--){scope.pageList.push(scope.conf.currentPage - i);}scope.pageList.push(scope.conf.currentPage);for(i = 1; i <= offset/2; i++){scope.pageList.push(scope.conf.currentPage + i);}scope.pageList.push('...');scope.pageList.push(scope.conf.numberOfPages);}}if(scope.conf.onChange){//请求数据if(scope.conf.search) {scope.conf.onChange();scope.conf.search = false;}}scope.$parent.conf = scope.conf;}// prevPagescope.prevPage = function(){if(scope.conf.currentPage > 1){scope.conf.currentPage -= 1;}};// nextPagescope.nextPage = function(){if(scope.conf.currentPage < scope.conf.numberOfPages){scope.conf.currentPage += 1;}};// 跳转页scope.jumpToPage = function(){scope.jumpPageNum = scope.jumpPageNum.replace(/[^0-9]/g,'');if(scope.jumpPageNum !== ''){scope.conf.currentPage = scope.jumpPageNum;}};scope.$watch(function() {if(!scope.conf.totalItems) {scope.conf.totalItems = 0;}if(angular.isUndefined(scope.conf.search)) {scope.conf.search = false;}var newValue = [scope.conf.totalItems, scope.conf.currentPage, scope.conf.itemsPerPage, scope.conf.search];return newValue;}, getPagination, true);}};
}]);

AngularJS自定义指令详解(有分页插件代码)相关推荐

  1. angularJS自定义指令详解

    AngularJS指令在HTML代码中可以有四种表现形式: 1.作为一个新的HTML元素来使用. <hello></hello>或者<hello/> 2.作为一个元 ...

  2. Vue自定义指令详解

    一.为什么需要自定义指令? 因为vue是MVVM模式,只需要关注于数据和业务逻辑,不需要关注DOM的操作,但是有时候面对一些特殊的业务需求时,需要进行DOM的操作,这个时候就需要进行自定义指令. 二. ...

  3. angular的自定义指令---详解

    1.angualr指令 在angualr自己里面有许多丰富的指令,但都是平时所常见的,但对于自己所需要的可能有所欠缺,所以自己可能会摒弃原声指令,自己封装更为健壮灵活的指令: 其实angular里面的 ...

  4. Vue中过滤器和自定义指令详解

    目录 1,局部过滤器 1.1定义: 1.2案例 2,全局过滤器 2.1定义: 2.2案例 3.自定义指令 3.1定义: 3.2案例 3.3自定义指令全局写法 1,局部过滤器 1.1定义: Vue.js ...

  5. Vue高级语法(一) | 自定义指令详解

    文章目录 Vue中自定义指令

  6. angular 定义对象_angular 自定义指令详解

    一:指令的创建 创建module: var module1 = angular.module('module1',[]); angular.bootstrap(document.body,['modu ...

  7. java中Freemarker list指令详解

    java Freemarker中list指令主要是进行迭代服务器端传递过来的List集合. 定义 <#list nameList as names> ${names} </#list ...

  8. angularjs directive 实例 详解

    angularjs directive 实例 详解 张映 发表于 2014-03-13 前面提到了angularjs的factory,service,provider,这个可以理解成php的model ...

  9. Angular ng-model指令详解

    Angular ng-model指令详解 声明 将输入域的值与 AngularJS 创建的变量绑定 双向数据绑定 表单验证 自定义类样式 常用应用状态 声明 本文根据菜鸟教程整理 http://www ...

最新文章

  1. html label标签 ie6,说说HTML5中label标签的可访问性问题
  2. Python3 下找不到urllib2的问题
  3. 光纤传感器实验模块_实验3振动测量试验模块.doc
  4. springboot JPA 做security的时候出现查了user表却不自动查role表 报 session为空
  5. 【转】推荐几本学习MySQL的好书-MySQL 深入的书籍
  6. 15日精读掌握《高德纳:具体数学》计划完成报告
  7. 计算机装固态硬盘,电脑怎么装固态硬盘?电脑加装固态硬盘步骤教程
  8. QtCharts:给QChartView换肤,换背景色添加背景图片
  9. python数组求和_python数组求和
  10. 锂离子电容器_离子电容器:从Mac的App到iOS IPA
  11. WINVNC源码阅读(二)
  12. SDN控制器与交换机如何建立连接
  13. 怎么都2200年了,还有人不愿意交社保???
  14. 表单验证工具类ValidationUtils
  15. 基于SVM算法的男女生分类器
  16. JDK8u201安装
  17. FFmpeg:截取视频片段转成GIF动画
  18. matlab访问被拒绝,安装MATLAB拒绝访问问题的解决方法
  19. Arduino 无源蜂鸣器实验
  20. html静态商城网页制作 基于HTML+CSS+JavaScript在线服装商城店铺商城设计毕业论文源码

热门文章

  1. python——类和对象之私有属性
  2. [HOW TO]-github/gitee的仓库统一管理
  3. Dockerfile 部署Djano项目
  4. Docker中的网络问题
  5. Ubuntu 环境中多线程下载工具Axel的安装与使用
  6. 12、INNER JOIN:内连接
  7. ACM入门之【并查集】
  8. 项目: 推箱子图形化游戏 【C++ / C】
  9. Bootstrap的引用文件
  10. python profile_python程序之profile分析