本篇实践一个案例,大致是:左边有导航菜单,右边显示列表,并可对列表项编辑或删除,也可添加新的列表项。借此,可体会到:如何组织可扩展的AngualrJS文件结构,如何点击左侧菜单项右侧显示相应内容,angular-ui-router的使用以及嵌套state,增删改查,等等。

大致如下:

当点击添加按钮:

当点击更新按钮:

文件结构

node_modules/
src/
.....app/
..........categories/  
...............categories.js  <包含一个名称为categories的module>
...............categories.tmpl.html <左侧的导航菜单>
...............bookmarks/
....................bookmark.js <包含一个名称为categories.bookmarks的module>
....................bookmarks.tmpl.html <右侧的列表项>
....................create/
.........................bookmark-create.js <包含一个名称为categories.bookmarks.create的module>
.........................bookmark-create.tmpl.html <添加表单>
....................edit/
.........................bookmark-edit.js <包含一个名称为categories.bookmarks.edit>
.........................bookmark-edit.tmpl.html <更新表单>
..........common/
...............models/
....................bookmarks-model.js <包含一个名称为darren.models.bookmarks的module>
....................categoires-model.js <包含一个名称为darren.models.categories的module>
..........app.js <包含一个名称为darren的module>
.....asserts/
..........css/
...............animation.css <有关state对应视图间切换的动画效果>
...............darren.css <项目css>
...............normalize.css
..........img/
...............logo.png
.....data/
..........bookmarks.json <右侧列表的json数据>
..........categories.json <左侧菜单的json数据>
.....vendor/
..........angular-ui-router.min.js
..........lodash.min.js
index.html

modules

modules之间的相互依赖如图:

万剑归一,所有的module都和名称为Darren的主module产生了联系。

index.html

<!--引用的css-->

<link rel="stylesheet" href="assets/css/normalize.css"/>
<link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.min.css"/>
<link rel="stylesheet" href="assets/css/eggly.css"/>
<link rel="stylesheet" href="assets/css/animations.css"/> <!--左侧菜单->
<div ui-view="categories"></div> <!--右侧列表-->
<div ui-view="bookmarks"></div> <!--引用的js--> <script src="../node_modules/jquery/dist/jquery.min.js"></script>
<script src="../node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="vendor/lodash.min.js"></script>
<script src="../node_modules/angular/angular.min.js"></script>
<script src="../node_modules/angular-animate/angular-animate.min.js"></script>
<script src="vendor/angular-ui-router.min.js"></script> <!--以下引用js的顺序和module之间的依赖关系基本一致-->
<script src="app/app.js"></script>
<script src="app/categories/categories.js"></script>
<script src="app/categories/bookmarks/bookmark.js"></script>
<script src="app/categories/bookmarks/create/bookmark-create.js"></script>
<script src="app/categories/bookmarks/edit/bookmark-edit.js"></script>
<script src="app/common/models/bookmarks-model.js"></script>
<script src="app/common/models/categories-model.js"></script>

以上,<div ui-view="categories"></div>和<div ui-view="bookmarks"></div>的数据从某个state中来,再具体定义state之前,首先先定义一个抽象的state,是在app.js中定义的。

app.js

名称为Darren的主module就定义在这里,并在module中定义了一个抽象sate,以便state的继承和嵌套。

angular.module('Darren', ['ngAnimate',
'ui.router',
'categories',
'categories.bookmarks'
])
.config(function($stateProvider, $urlRouterProvider){ //默认情况下导航到首页
$stateProvider
.state('darren',{
url: '',
abstract: true
});
$urlRouterProvider.otherwise('/');
})
;

现在,应该到具体的state了,把index.html中<div ui-view="categories"></div>和<div ui-view="bookmarks"></div>的数据显示出来,但我们还没有看过数据源呢,本项目的数据源是以json形式存在的。

数据源

categories.json

[
  {"id": 0, "name": ""},
  {"id": 1, "name": ""},
  {"id": 2, "name": ""},
  {"id": 3, "name": ""}
]

bookmarks.json

[
  {"id":0, "title": "", "url": "", "category": "" },
  {"id":1, "": "", "url": "", "category": "" },
  ...
]

接下来就是对这些数据的操作,所有针对category和bookmark的操作都放在了service中。

categories-model.js

这里定义了针对category的service。

angular.module('darren.models.categories',[])
.service('CategoriesModel', function($http, $q){ var model=this,
URLS={
FETCH:'data/categories.json'
},
categories,
currentCategory; model.getCategoires = function(){ //如果categories存在,使用$q返回promise
//如果不存在才去提取数据
return (categories) ? $q.when(categories) : $http.get(URLS.FETCH).then(cacheCategories);
} function extract(result){
return result.data;
} function cacheCategories(result){
categories = extract(result);
return categories;
} model.getCategoryByName = function(categoryName){
var defered = $q.defer(); function findCategory(){
return _.find(categories, function(c){
return c.name == categoryName;
});
} if(categories){
defered.resolve(findCategory());
} else{
model.getCategoires()
.then(function(result){
defered.resolve(findCategory());
});
} return defered.promise;
}; model.setCurrentCategory = function(categoryName){
return model.getCategoryByName(categoryName)
.then(function(category){
currentCategory = category;
});
}; model.getCurrentCategory = function(){
return currentCategory;
} model.getCurrentCategoryName = function(){
return currentCategory ? currentCategory.name : '';
}; })
;

以上,
● 对外提供了getCategories方法

如果categories存在,通过$q.when返回promise,如果categories不存在,通过或$http.get结合then返回一个promoise。

● 对外提供了getCategoryByName方法,根据categoryName获取category

通过$q.defer返回一个deferred对象,通过defered.promise返回promise。其中定义了一个内部函数findCategory,通过lodash的find方法获取到要找的category,如果categories存在,就使用deferred.reslove当前category, 如果categories不存在,就调用getCategories方法获取到categories后在defered.resolve。

● 对外提供了setCurrentCategory方法

把获取到的category赋值给了一个currentCategory变量。当点击界面上左侧菜单项的时候需要调用这个方法。

● 对外提供了getCurrentCategory方法

实际是返回currentCategory这个变量值。

● 对外getCurrentCategoryName方法

如果currentCategory变量值为null,就返回空字符串,如果不是null,那就返回currentCategory的name字段值。

接下来,就是针对bookmark的servcie。

bookmarks-model.js

angular.module('darren.models.bookmarks',[])
.service('BookmarksModel', function($http, $q){
var model = this,
bookmarks,
URL={
FETCH: 'data/bookmarks.json'
}; //获取
model.getBookmarks = function(){ var deferred = $q.defer(); if(bookmarks){
deferred.resolve(bookmarks);
} else{
$http.get(URL.FETCH).then(function(bookmarks){
deferred.resolve(cacheBookmarks(bookmarks));
});
} return deferred.promise;
} function extract(result){
return result.data;
} function cacheBookmarks(result){
bookmarks = extract(result);
return bookmarks;
} //创建
model.createBookmark = function(bookmark){
bookmark.id = bookmarks.length;
bookmarks.push(bookmark);
} //根据编号查找
function findBookmark(bookmarkId){
return _.find(bookmarks, function(bookmark){
return bookmark.id === parseInt(bookmarkId, 10);
});
} model.getBookmarkById = function(bookmarkId){
//创建defered object
var deferred = $q.defer(); if(bookmarks){
deferred.resolve(findBookmark(bookmarkId));
} else{
model.getBookmarks().then(function(){
deferred.resolve(findBookmark(bookmarkId));
});
} return deferred.promise;
} //更新
model.updateBookmark = function(bookmark){
var index = _.findIndex(bookmarks, function(b){
return b.id == bookmark.id;
}); bookmarks[index] = bookmark;
} //删除
model.deleteBookmark = function(bookmark){
_.remove(bookmarks, function(item){
return item.id == bookmark.id;
});
}
})
;

以上,

● 对外提供getBookmarks方法

也是返回以promise类型的bookmarks。

● 对外提供createBookmark方法,接受bookmark形参

就是给bookmark赋一个id值,然后放到当前的bookmarks数组中。

● 对外提供getBookmarkById方法,根据bookmarkId形参获取

返回一个promise的bookmark。

● 对外提供updateBookmark,接受bookmark形参

使用lodash的findIndex方法获取当前bookmark在数组中的索引值,再根据这个索引值为对应的数组元素赋上新值。

● 对外提供deleteBookmark方法,接受bookmark形参

使用lodash的remove方法删除数组元素。

好了,数据源以及操作数据的各种方法都具备了,现在就到了路由,控制器等了。

category.js

还记得首页<div ui-view="categories"></div>和<div ui-view="bookmarks"></div>中的数据还没着落吗?其实是在这里定义的。

angular.module('categories',[
'darren.models.categories'
])
.config(function($stateProvider){
$stateProvider
.state('darren.categories',{
url: '/',
views: {
//target the ui-view named categories in root state
'categories@':{
controller: 'CategoriesCtrl as categoriesListCtrl',
templateUrl: 'app/categories/categories.tmpl.html'
},
//target the ui-view named 'bookmarks' in root state to show all bookmarks for all categories
'bookmarks@':{
controller: 'BookmarksCtrl as bookmarksListCtrl',
templateUrl: 'app/categories/bookmarks/bookmarks.tmpl.html'
}
}
});
})
.controller('CategoriesCtrl', function CategoriesCtrl(CategoriesModel){
var categoriesListCtrl = this; CategoriesModel.getCategoires()
.then(function(result){
categoriesListCtrl.categories = result;
}); })
;

以上,

● 定义了一个名称为darren.categories的state

url: '/'表示首页url路径,views字段中定义了两组controller和templateUrl的配对。categories@对应首页视图中的<div ui-view="categories"></div>,bookmarks@对应首页视图中的<div ui-view="bookmarks"></div>。

在 controller: 'CategoriesCtrl as categoriesListCtrl'中,CategoriesCtrl这个控制器有了别名,也就意味着如果在界面中调用CategoriesCtrl就使用它的别名categoriesListCtrl。

现在,有关state的关系如下:

当在首页,即路径是/,首先经过类型为abstract名称为darren的state,然后来到darren.categories(这里的书写格式符合惯例:上一级.下一级)这个state,页面上的<div ui-view="categories"></div>找到这里的categories@字段,就让categorieslistCtrl负责为categories.tmpl.html这个视图提供数据。

<div ui-view="bookmarks"></div>找到这里的bookmarks@字段,让bookmarksListCtrl和bookmarks.tmpl.html配对,可这里的问题是:bookmarksListCtrl并不在categories这个module中,到底是去哪里找bookmarksListCtrl了?

● 定义了控制器,对外通过了categores这个字段

在控制器中注入了CategoriesModel这个service,通过该service获取到数据。

categories.tmpl.html

这里即是首页左侧菜单。

<ul>
<!--判断是否为选中的category,逻辑是点击当前的category,把这个category保存在$scope.currentCategory中,再判断当前的category是否和$scope.currentCategory相等,相等就为选中状态。就像非常勿扰女嘉宾按灯,系统就记录下当前按灯的桌号,系统再遍历所有的桌号,如果桌号和系统记录的桌号相等,就让该桌号的灯亮起来,道理是一样一样滴。-->
<li ng-repeat="category in categoriesListCtrl.categories">
<a ui-sref="darren.categories.bookmarks({category:category.name})">
{{category.name}}
</a>
</li>
</ul>

以上,好玩的是ui-sref="darren.categories.bookmarks({category:category.name}),也就是说,当点击左侧的某个菜单项,就指向darren.categories.bookmarks这个state,并带着参数category,之所以把category的name键值传递出去,是因为在右侧列表项要显示点击了哪个类别。

darren.categories.bookmarks这个state被定义在了bookmark.js中了。

bookmark.js

angular.module('categories.bookmarks',[
'categories.bookmarks.create',
'categories.bookmarks.edit',
'darren.models.bookmarks'
])
.config(function($stateProvider){
$stateProvider
.state('darren.categories.bookmarks',{
url: 'categories/:category',
views: {
'bookmarks@':{
templateUrl: 'app/categories/bookmarks/bookmarks.tmpl.html',
controller:'BookmarksCtrl as bookmarksListCtrl'
}
}
});
}) //不需要$scope的写法
.controller('BookmarksCtrl', function($stateParams,BookmarksModel,CategoriesModel){
var bookmarksListCtrl = this; CategoriesModel.setCurrentCategory($stateParams.category); BookmarksModel.getBookmarks()
.then(function(bookmarks){
bookmarksListCtrl.bookmarks = bookmarks;
}); bookmarksListCtrl.getCurrentCategory = CategoriesModel.getCurrentCategory;
bookmarksListCtrl.getCurrentCategoryName = CategoriesModel.getCurrentCategoryName;
bookmarksListCtrl.deleteBookmark = BookmarksModel.deleteBookmark; })
;

以上,在categories.tmpl.html中点击菜单项(ui-sref="darren.categories.bookmarks({category:category.name}))传递出的category是和这里的categories/:category对应。

具体来说,当点击菜单项(ui-sref="darren.categories.bookmarks({category:category.name})),来到darren.categories.bookmarks这个state,且url符合categories/:category格式,stateParams把url中的category存储下来,首页上的<div ui-view="bookmarks"></div>找到bookmarks@字段,最终把bookmarksListCtrl和bookmarks.tmpl.html匹配。

另外,在category.js中,还提到了这样的一个问题:bookmarksListCtrl并不在categories这个module中,到底是去哪里找bookmarksListCtrl了?在这里也找到了答案,当在categories这个module中没有bookmarksListCtrl的时候,会按照darren→darren.categores→darren.categores.bookmarks整条线路找到bookmarks$对应的controller和view的匹配。

bookmarks.tmpl.html

<!--不使用$scope的写法,给controller别名的写法-->
<h1>{{bookmarksListCtrl.getCurrentCategoryName()}}</h1> <!--对bookmarks进行了过滤,过滤的标准是bookmark的字段category-->
<div ng-repeat="bookmark in bookmarksListCtrl.bookmarks | filter:{category:bookmarksListCtrl.getCurrentCategoryName()}">
<button type="button" class="close" ng-click="bookmarksListCtrl.deleteBookmark(bookmark)">&times;</button>
<button type="button" class="btn btn-link" ui-sref="darren.categories.bookmarks.edit({bookmarkId: bookmark.id})">更新</button>
<a href="{{bookmark.url}}" target="_blank">{{bookmark.title}}</a>
</div>
<hr/>
<!-- CREATING -->
<ui-view ng-if="bookmarksListCtrl.getCurrentCategory()">
<button type="button" ui-sref="darren.categories.bookmarks.create">添加</button>
</ui-view>

以上,

点击更新按钮,ui-sref="darren.categories.bookmarks.edit({bookmarkId: bookmark.id})",来到了darren.categories.bookmarks.edit这个state,并带上了bookmarkId这个参数,这个state被定义在了bookmark-edit.js中了。

点击添加按钮。ui-sref="darren.categories.bookmarks.create",来到darren.categories.bookmarks.create这个state,这个state被定义在了bookmark-create.js中了。

即<ui-view></ui-view>中显示的内容有可能是添加的内容,也有可能是更新的内容。

bookmark-edit.js

angular.module('categories.bookmarks.edit',[])
.config(function($stateProvider){
$stateProvider
.state('darren.categories.bookmarks.edit',{
url: '/bookmarks/:bookmarkId/edit',
templateUrl: 'app/categories/bookmarks/edit/bookmark-edit.tmpl.html',
controller: 'EditBookmarkCtrl as editBookmarkCtrl'
});
})
.controller('EditBookmarkCtrl', function($state, $stateParams, BookmarksModel){
var editBookmarkCtrl = this; //更新成功或取消更新
function returnToBookmarks(){
$state.go('darren.categories.bookmarks',{
category: $stateParams.category
});
} function cancelEditing(){
returnToBookmarks();
} //editBookmarkCtrl.bookmark
//editBookmarkCtrl.editedBookmark
BookmarksModel.getBookmarkById($stateParams.bookmarkId)
.then(function(bookmark){
if(bookmark){
editBookmarkCtrl.bookmark = bookmark;
editBookmarkCtrl.editedBookmark = angular.copy(editBookmarkCtrl.bookmark);
} else {
returnToBookmarks();
}
}); //更新
function updateBookmark(){
editBookmarkCtrl.bookmark = angular.copy(editBookmarkCtrl.editedBookmark);
BookmarksModel.updateBookmark(editBookmarkCtrl.bookmark);
returnToBookmarks();
} editBookmarkCtrl.cancelEditing = cancelEditing;
editBookmarkCtrl.updateBookmark = updateBookmark;
})
;

以上,点击更新按钮,ui-sref="darren.categories.bookmarks.edit({bookmarkId: bookmark.id})"中的bookmarkId被url: '/bookmarks/:bookmarkId/edit'接受。state之间的关系现在变成这样:

具体来说,点击更新按钮,ui-sref="darren.categories.bookmarks.edit({bookmarkId: bookmark.id})"来到darren.categories.bookmarks.edit这个state,其中的bookmarkId被$stateParams.bookmarkId接受,配对editBookmarkCtrl和bookmark-edit.tmpl.html,bookmark-edit.tmpl.html的内容显示在bookmarks.tmpl.html中的<ui-view></ui-view>里。

bookmark.edit.tmpl.html

<h4>Editing {{editBookmarkCtrl.bookmark.title}}</h4>
<form class="edit-form" role="form" ng-submit="editBookmarkCtrl.updateBookmark(editBookmarkCtrl.editedBookmark)" novalidate>
<div class="form-group">
<label>Bookmark Title</label>
<input type="text" class="form-control" ng-model="editBookmarkCtrl.editedBookmark.title" placeholder="Enter title">
</div>
<div class="form-group">
<label>Bookmark URL</label>
<input type="text" class="form-control" ng-model="editBookmarkCtrl.editedBookmark.url" placeholder="Enter URL">
</div>
<button type="submit" class="btn btn-info btn-lg">Save</button>
<button type="button" class="btn btn-default btn-lg pull-right" ng-click="editBookmarkCtrl.cancelEditing()">Cancel</button>
</form>

bookmark-create.js

点击添加按钮。ui-sref="darren.categories.bookmarks.create",这里的darren.categories.bookmarks.create定义在了bookmark-create.js中。

angular.module('categories.bookmarks.create',[])

    .config(function($stateProvider){
$stateProvider
.state('darren.categories.bookmarks.create',{
url: '/bookmarks/create',
templateUrl: 'app/categories/bookmarks/create/bookmark-create.tmpl.html',
controller: 'CreateBookmarkCtrl as createBookmarkCtrl'
});
})
.controller('CreateBookmarkCtrl', function($state, $stateParams, BookmarksModel){
var createBookmarkCtrl = this; //添加或取消完成后执行
function returnToBookmarks(){
$state.go('darren.categories.bookmarks',{
category: $stateParams.category
});
} //取消
function cancelCreating(){
returnToBookmarks();
} //添加
function createBookmark(bookmark){
BookmarksModel.createBookmark(bookmark);
returnToBookmarks();
} createBookmarkCtrl.cancelCreating = cancelCreating;
createBookmarkCtrl.createBookmark = createBookmark; //重置表单
function resetForm(){
createBookmarkCtrl.newBookmark = {
title: '',
url: '',
category: $stateParams.category
};
} resetForm();
})
;

state之间的关系现在变成这样:

具体来说,点击添加按钮。ui-sref="darren.categories.bookmarks.create",来到darren.categories.bookmarks.create这个state,由于url和url: '/bookmarks/create'格式一致,配对createBookmarkCtrl和bookmark-create.tmpl.html,上级state中的$stateParams.category被这里运用到。

bookmark-create.tmpl.html

<form class="create-form" role="form" ng-submit="createBookmarkCtrl.createBookmark(createBookmarkCtrl.newBookmark)" novalidate>
<div class="form-group">
<label for="newBookmarkTitle">Bookmark Title</label>
<input type="text" class="form-control" id="newBookmarkTitle" ng-model="createBookmarkCtrl.newBookmark.title" placeholder="Enter title">
</div>
<div class="form-group">
<label for="newBookmarkURL">Bookmark URL</label>
<input type="text" class="form-control" id="newBookmarkURL" ng-model="createBookmarkCtrl.newBookmark.url" placeholder="Enter URL">
</div>
<button type="submit" class="btn btn-info btn-lg">Create</button>
<button type="button" class="btn btn-default btn-lg pull-right" ng-click="createBookmarkCtrl.cancelCreating()">Cancel</button>
</form>

结束。☺

AngularJS的增删改查、state嵌套案例,不涉及服务端的更多相关文章

  1. Python列表的增删改查排嵌套特殊输出格式

    Python列表的增删改查排嵌套特殊输出格式 一.列表的样子: a = ['q' , 'w' , 'e ', 'r','t'] a为列表名,[ ]为列表内容,' '为列表内的元素,'q'为a[0] 二 ...

  2. python之路day05--字典的增删改查,嵌套

    字典dic 数据类型划分:可变数据类型,不可变数据类型 不可变数据类型:元组,bool,int str -->可哈希可变数据类型:list,dict,set --> 不可哈希 dict k ...

  3. python之路day04--列表的增删改查,嵌套、元组的嵌套、range、for循环嵌套

    列表增删改查 增加 append li = ['taibai','zy','nvshen'] li.append('aa') print(li) #['taibai', 'zy', 'nvshen', ...

  4. thinkPHP增删改查的方法案例

    thinkphp对数据库增删改查进行了封装操作,使得使用更加方便,但是不一定灵活. 可以用封装的用,需要写sql,可以执行sql. 1.原始的 $Model = new Model(); // 实例化 ...

  5. python列表的增删改查和嵌套

    列表 python常用的数据类型 可承载任意的数据类型 列表是有序的,可索引.切片(步长) 列表的创建 list1 = [1, 2, 'whll'] #1. list2 = list() #2. #3 ...

  6. Python字典的初识、增删改查及嵌套

    为什么要有字典? 列表可以存储大量的数据,但数据间的关联型不强 列表的查询速度相对慢 dict:字典,容器型数据类型 数据类型的分类: 可变与不可变 可变(不可哈希)的数据类型: 列表list,字典d ...

  7. Dapper逆天入门~强类型,动态类型,多映射,多返回值,增删改查+存储过程+事物案例演示

    Dapper的牛逼就不扯蛋了,答应群友做个入门Demo的,现有园友需要,那么公开分享一下: 完整Demo:http://pan.baidu.com/s/1i3TcEzj 注 意 事 项:http:// ...

  8. 【转载】ASP.NET MVC Web API 学习笔记---联系人增删改查

    本章节简单介绍一下使用ASP.NET MVC Web API 做增删改查.目前很多Http服务还是通过REST或者类似RESP的模型来进行数据操作的.下面我们通过创建一个简单的Web API来管理联系 ...

  9. ASP.NET MVC Web API 学习笔记---联系人增删改查

    本章节简单介绍一下使用ASP.NET MVC Web API 做增删改查. 目前很多Http服务还是通过REST或者类似RESP的模型来进行数据操作的. 下面我们通过创建一个简单的Web API来管理 ...

随机推荐

  1. Workflow规则收藏

    豆瓣电影  查看电影评分等详细信息 查看图片EXIF 图铃机器人 快递查询 翻译 手机号码归属地 音乐视频下载 获取附近的免费WIFI

  2. WPF使用DataGridComboBoxColumn完成绑定

    在使用DataGrid的时候,有时候需要使某些列为ComboBox,这时自然想到使用DataGridComboBoxColumn,但是如果使用的是ItemsSource数据绑定后台的对象,就会发现,这 ...

  3. vs 连接过程报错 dll 分析 ------- DLL动态链接库

    1:编译成功,说明代码没有问题了2:连接报错,说明 exe 在查找dll 的入口地址过程,找不到合适的信息,这些信息保存在 dll 对应的 *.lib 文件里面  说明:exe如果生成成功了lib 这 ...

  4. dataframe 差集

    >>>data_a={'state':[1,1,2],'pop':['a','b','c']}>>>data_b={'state':[1,2,3],'pop':[' ...

  5. tensorflow-训练(train)/测试(test)

    一个TFRecords 文件为一个字符串序列.这种格式并非随机获取,它比较适合大规模的数据流,而不太适合需要快速分区或其他非序列获取方式. 操作组 操作 Training Optimizers,Gra ...

  6. EFCore CodeFirst 适配数据库

    EF6中可以直接根据代码模型生成数据库Database.SetInitializer即可 在EFCore中如何实现呢? 这项功能放在了DatabaseFacade对象中,传入数据库上下文对象实例化到一 ...

  7. 【PAT】1032 Sharing (25)(25 分)

    1032 Sharing (25)(25 分) To store English words, one method is to use linked lists and store a word l ...

  8. Linux 获取目录中最后一个文件的名字

    find /application/docker_hub/logs/fof1private/amount_dev -type l | xargs basename

  9. Exception in thread "main" java.net.SocketTimeoutException: connect timed ou错误处理

    今天做了一个Jsoup解析网站的项目,使用Jsoup.connect(url).get()连接某网站时偶尔会出现java.net.SocketTimeoutException:Read timed o ...

  10. python 实现结构体

    # python 使用类创建结构体 class Myclass(object): class Struct(object): def __init__(self, name, age, job): s ...