ReactiveCocoa框架下的MVVM模式解读
记录一些MVVM文章中关于ReactiveCocoa的代码:
实例一:带有分页的文章列表,根据文章类别过滤出文章的列表,可以进入文章详细页面
1:YFBlogListViewModel 首先了解关于列表的ViewModel的代码内容:
#import <Foundation/Foundation.h>
#import <ReactiveCocoa.h> @class YFCategoryArticleListModel; /**
* 文章列表的视图模型.
*/
@interface YFBlogListViewModel : NSObject
@property (copy, nonatomic) NSArray * blogListItemViewModels; //!< 文章.内部存储的应为文章列表单元格的视图模型.注意: 刷新操作,存储第一页数据;翻页操作,将存储所有的数据,并按页面排序. /**
* 使用一个分类文章列表数据模型来快速初始化.
*
* @param model 文章列表模型.
*
* @return 实例对象.
*/ - (instancetype)initWithCategoryArtilceListModel: (YFCategoryArticleListModel *) model; /**
* 获取首页的数据.常用于下拉刷新.
*
*/
- (void)first; /**
* 翻页,获取下一页的数据.常用于上拉加载更多.
*/
- (void)next; @end
#import "YFBlogListViewModel.h"
#import <ReactiveCocoa.h>
#import <AFNetworking.h>
#import <RACAFNetworking.h>
#import "YFCategoryArticleListModel.h"
#import <MJExtension.h>
#import "YFBlogListItemViewModel.h"
#import "YFArticleModel.h" @interface YFBlogListViewModel ()
@property (strong, nonatomic) AFHTTPRequestOperationManager * httpClient;
@property (strong, nonatomic) NSNumber * nextPageNumber; //!< 下次要请求第几页的数据.
@property (copy, nonatomic) NSString * category; //!< 文章类别.
@property (copy, nonatomic) NSString * requestPath; //!< 完整接口地址. @end @implementation YFBlogListViewModel - (instancetype)initWithCategoryArtilceListModel:(YFCategoryArticleListModel *)model
{
self = [super init]; if (nil != self) {
// 设置 self.category 与 model.category 的关联.
[RACObserve(model, category) subscribeNext:^(NSString * categoryName) {
self.category = categoryName;
}]; // 和类型无关的RAC 初始化操作,应该剥离出来.
[self setup];
} return self;
} /**
* 和数据模型无关的初始化设置,放到独立的方法中.
*/
- (void)setup
{
// 初始化网络请求相关的信息.
self.httpClient = [AFHTTPRequestOperationManager manager];
self.httpClient.requestSerializer = [AFJSONRequestSerializer serializer];
self.httpClient.responseSerializer = [AFJSONResponseSerializer serializer]; // 设置 self.nextPageNumber 与self.category的关联.
[RACObserve(self, category) subscribeNext:^(id x) {
// 只要分类变化,下次请求,都需要重置为请求第零页的数据.
self.nextPageNumber = @;
}]; // 接口完整地址,肯定是受分类和页面的影响的.但是因为分类的变化最终会通过分页的变化来体现,所以此处仅需监测分页的变化情况即可.
[RACObserve(self, nextPageNumber) subscribeNext:^(NSNumber * nextPageNumber) {
NSString * path = [NSString stringWithFormat: @"http://www.ios122.com/find_php/index.php?viewController=YFPostListViewController&model[category]=%@&model[page]=%@", self.category, nextPageNumber]; self.requestPath = path;
}]; // 每次数据完整接口变化时,必然要同步更新 blogListItemViewModels 的值.
[[RACObserve(self, requestPath) filter:^BOOL(id value) {
return value;
}] subscribeNext:^(NSString * path) {
/**
* 分两种情况: 如果是变为0,说明是重置数据;如果是大于0,说明是要加载更多数据;不处理向上翻页的情况.
*/ NSMutableArray * articls = [NSMutableArray arrayWithCapacity: ]; if (YES != [self.nextPageNumber isEqualToNumber: @]) {
[articls addObjectsFromArray: self.blogListItemViewModels];
} [[self.httpClient rac_GET:path parameters:nil] subscribeNext:^(RACTuple *JSONAndHeaders) {
// 使用MJExtension将JSON转换为对应的数据模型.
NSArray * newArticles = [YFArticleModel objectArrayWithKeyValuesArray: JSONAndHeaders.first]; // RAC 风格的数组操作.
RACSequence * newblogViewModels = [newArticles.rac_sequence
map:^(YFArticleModel * model) {
YFBlogListItemViewModel * vm = [[YFBlogListItemViewModel alloc] initWithArticleModel: model]; return vm;
}]; [articls addObjectsFromArray: newblogViewModels.array]; self.blogListItemViewModels = articls;
}];
}];
} - (void)first
{
self.nextPageNumber = @;
} - (void)next
{
self.nextPageNumber = [NSNumber numberWithInteger: [self.nextPageNumber integerValue] + ];
} @end
2:YFCategoryArticleListModel模型的内容
#import <Foundation/Foundation.h> /**
* 分类文章列表.
*/
@interface YFCategoryArticleListModel : NSObject
@property (copy, nonatomic) NSString * category; //!< 分类
@property (strong, nonatomic) NSArray * articles; //!< 此分类下的文章列表. @end
3:ViewController的代码
#import <UIKit/UIKit.h> @class YFBlogListViewModel; @interface YFMVVMPostListViewController : UIViewController<UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, strong) UITableView * tableView;
@property (strong, nonatomic) YFBlogListViewModel * viewModel; @end
#import "YFMVVMPostListViewController.h"
#import "YFBlogListViewModel.h"
#import <ReactiveCocoa.h>
#import "YFCategoryArticleListModel.h"
#import "YFBlogListViewModel.h"
#import "YFBlogListItemViewModel.h"
#import "YFArticleModel.h"
#import "YFBlogDetailViewModel.h"
#import <MJRefresh.h>
#import "YFMVVMPostViewController.h" @interface YFMVVMPostListViewController () @end @implementation YFMVVMPostListViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view. [RACObserve(self.viewModel, blogListItemViewModels) subscribeNext:^(id x) {
[self updateView];
}];
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} - (UITableView *)tableView
{
if (nil == _tableView) {
_tableView = [[UITableView alloc] init]; [self.view addSubview: _tableView]; [_tableView makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(UIEdgeInsetsMake(, , , ));
}]; _tableView.delegate = self;
_tableView.dataSource = self; NSString * cellReuseIdentifier = NSStringFromClass([UITableViewCell class]); [_tableView registerClass: NSClassFromString(cellReuseIdentifier) forCellReuseIdentifier:cellReuseIdentifier]; _tableView.header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
[self.viewModel first];
}]; _tableView.footer = [MJRefreshBackNormalFooter footerWithRefreshingBlock:^{
[self.viewModel next];
}]; } return _tableView;
} /**
* 更新视图.
*/
- (void) updateView
{
[self.tableView.header endRefreshing];
[self.tableView.footer endRefreshing]; [self.tableView reloadData];
} # pragma mark - tabelView代理方法. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger number = self.viewModel.blogListItemViewModels.count; return number;
} - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString * cellReuseIdentifier = NSStringFromClass([UITableViewCell class]); UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: cellReuseIdentifier forIndexPath:indexPath]; YFBlogListItemViewModel * vm = self.viewModel.blogListItemViewModels[indexPath.row]; NSString * content = vm.intro; cell.textLabel.text = content; cell.selectionStyle = UITableViewCellSelectionStyleNone; return cell;
} - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// 跳转到博客详情.
YFBlogListItemViewModel * itemVM = self.viewModel.blogListItemViewModels[indexPath.row]; YFMVVMPostViewController * postVC = [[YFMVVMPostViewController alloc] init]; YFBlogDetailViewModel * detailVM = [[YFBlogDetailViewModel alloc] init];
detailVM.blogId = itemVM.blogId; postVC.viewModel = detailVM; [self.navigationController pushViewController: postVC animated: YES];
} @end
4:跳转到当前页面的内容
YFMVVMPostListViewController * mvvmPostVC = [[YFMVVMPostListViewController alloc] init]; YFCategoryArticleListModel * articleListModel = [[YFCategoryArticleListModel alloc] init];
articleListModel.category = @"ui"; YFBlogListViewModel * listVM = [[YFBlogListViewModel alloc] initWithCategoryArtilceListModel: articleListModel]; mvvmPostVC.viewModel = listVM; [self.navigationController pushViewController: mvvmPostVC animated: YES];
5:详细页面的ViewModel代码:
#import <Foundation/Foundation.h>
@class YFArticleModel; /**
* 文章详情的视图模型.
*/ @interface YFBlogDetailViewModel : NSObject
@property (copy, nonatomic) NSString * content; // 要显示的内容.
@property (copy, nonatomic) NSString * blogId; //!< 博客ID. - (instancetype)initWithModel: (YFArticleModel *) model; @end
#import "YFBlogDetailViewModel.h"
#import <ReactiveCocoa.h>
#import "YFArticleModel.h"
#import <RACAFNetworking.h>
#import <MJExtension.h> @interface YFBlogDetailViewModel ()
@property (strong, nonatomic) AFHTTPRequestOperationManager * httpClient;
@property (copy, nonatomic) NSString * requestPath; //!< 完整接口地址. @end
@implementation YFBlogDetailViewModel - (instancetype)init
{
self = [self initWithModel: nil]; return self;
} - (instancetype)initWithModel:(YFArticleModel *)model
{
self = [super init]; if (nil != self) {
// 设置self.blogId与model.id的相互关系.
[RACObserve(model, id) subscribeNext:^(id x) {
self.blogId = x;
}]; [self setup];
} return self;
} /**
* 公共的与Model无关的初始化.
*/
- (void)setup
{
// 初始化网络请求相关的信息.
self.httpClient = [AFHTTPRequestOperationManager manager];
self.httpClient.requestSerializer = [AFJSONRequestSerializer serializer];
self.httpClient.responseSerializer = [AFJSONResponseSerializer serializer]; // 接口完整地址,肯定是受id影响.
[[RACObserve(self, blogId) filter:^BOOL(id value) {
return value;
}] subscribeNext:^(NSString * blogId) {
NSString * path = [NSString stringWithFormat: @"http://www.ios122.com/find_php/index.php?viewController=YFPostViewController&model[id]=%@", blogId]; self.requestPath = path;
}]; // 每次完整的数据接口变化时,必然要同步更新 self.content 的值.
[[RACObserve(self, requestPath) filter:^BOOL(id value) {
return value;
}] subscribeNext:^(NSString * path) {
[[self.httpClient rac_GET:path parameters:nil] subscribeNext:^(RACTuple *JSONAndHeaders) {
// 使用MJExtension将JSON转换为对应的数据模型.
YFArticleModel * model = [YFArticleModel objectWithKeyValues:JSONAndHeaders.first]; self.content = model.body;
}];
}];
} @end
6:详细页面的ViewController
#import <UIKit/UIKit.h> @class YFBlogDetailViewModel; @interface YFMVVMPostViewController : UIViewController
@property (strong, nonatomic) YFBlogDetailViewModel * viewModel; @end
#import "YFMVVMPostViewController.h"
#import "YFBlogDetailViewModel.h"
#import <ReactiveCocoa.h> @interface YFMVVMPostViewController ()
@property (strong, nonatomic) UIWebView * webView;
@end @implementation YFMVVMPostViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[RACObserve(self.viewModel, content) subscribeNext:^(id x) {
[self updateView];
}];
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (UIWebView *)webView
{
if (nil == _webView) {
_webView = [[UIWebView alloc] init]; [self.view addSubview: _webView]; [_webView makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(UIEdgeInsetsMake(, , , ));
}];
} return _webView;
} /**
* 更新视图.
*/
- (void) updateView
{
[self.webView loadHTMLString: self.viewModel.content baseURL:nil];
} @end
实例二:用户列表实例
1:用户列表的ViewModel代码UsersViewModel
#import <ReactiveViewModel/ReactiveViewModel.h> @class RACCommand; #pragma mark - @interface UsersViewModel : RVMViewModel /// Array of UserViewModel objects filled by userViewModelsCommand.
@property (nonatomic, readonly) NSArray *userViewModels; /// Input: nil
@property (nonatomic, readonly) RACCommand *userViewModelsCommand; /// Input: nil
@property (nonatomic, readonly) RACCommand *clearImageCacheCommand; @property (nonatomic, readonly, getter=isLoading) BOOL loading; @end
#import "UsersViewModel.h" #import "UserViewModel.h" #import "UserController.h" #import "User.h" #import "ImageController.h" #import <ReactiveCocoa/ReactiveCocoa.h>
#import <ReactiveCocoa/RACEXTScope.h> #pragma mark - @implementation UsersViewModel - (instancetype)init {
self = [super init];
if (self) {
UserController *userController = [[UserController alloc] init];
ImageController *imageController = [ImageController sharedController]; _userViewModelsCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id _) {
return [[[userController fetchRandomUsers:]
subscribeOn:[RACScheduler scheduler]]
map:^NSArray *(NSArray *users) {
return [[[users rac_sequence]
map:^UserViewModel *(User *user) {
return [[UserViewModel alloc] initWithUser:user imageController:imageController];
}]
array];
}];
}]; RAC(self, userViewModels) =
[[[_userViewModelsCommand executionSignals]
switchToLatest]
deliverOn:[RACScheduler mainThreadScheduler]]; RAC(self, loading) =
[_userViewModelsCommand executing]; _clearImageCacheCommand = [[RACCommand alloc] initWithEnabled:[RACObserve(self, loading) not] signalBlock:^RACSignal *(id _) {
return [imageController purgeLocalCaches];
}];
}
return self;
} @end
2:另外封装UserController的代码:
@class RACSignal; #pragma mark - @interface UserController : NSObject /// Sends an array of fabricated User objects then completes.
- (RACSignal *)fetchRandomUsers:(NSUInteger)numberOfUsers; @end
#import "UserController.h" #import "User.h" #import <ReactiveCocoa/ReactiveCocoa.h>
#import <LoremIpsum/LoremIpsum.h> #pragma mark - @implementation UserController - (RACSignal *)fetchRandomUsers:(NSUInteger)numberOfUsers {
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSMutableArray *usersArray = [NSMutableArray array];
for (int i = ; i < numberOfUsers; i++) {
NSString *name = [LoremIpsum name];
NSURL *avatarURL = [[LoremIpsum URLForPlaceholderImageFromService:LIPlaceholderImageServiceHhhhold withSize:CGSizeMake(, )] URLByAppendingPathComponent:[NSString stringWithFormat:@"jpg?test=%i", i]];
User *user = [[User alloc] initWithName:name avatarURL:avatarURL];
[usersArray addObject:user];
}
[subscriber sendNext:[usersArray copy]];
[subscriber sendCompleted];
return nil;
}];
} @end
3:Model的代码:
#pragma mark - @interface User : NSObject @property (nonatomic, readonly) NSString *name;
@property (nonatomic, readonly) NSURL *avatarURL; - (instancetype)initWithName:(NSString *)name avatarURL:(NSURL *)avatarURL; @end
#import "User.h" #pragma mark - @implementation User - (instancetype)initWithName:(NSString *)name avatarURL:(NSURL *)avatarURL {
self = [super init];
if (self != nil) {
_name = name;
_avatarURL = avatarURL;
}
return self;
} @end
4:ViewController的代码
@class UsersViewModel; @interface UsersViewController : UITableViewController - (instancetype)initWithViewModel:(UsersViewModel *)viewModel; @end
#import "UsersViewController.h" #import "UsersViewModel.h"
#import "UserViewModel.h" #import "UserCell.h" #import <ReactiveCocoa/ReactiveCocoa.h>
#import <ReactiveCocoa/RACEXTScope.h> #pragma mark - @interface UsersViewController () @property (nonatomic, readonly) UsersViewModel *viewModel; @end @implementation UsersViewController - (instancetype)initWithViewModel:(UsersViewModel *)viewModel {
self = [super init];
if (self != nil) {
_viewModel = viewModel;
}
return self;
} - (void)viewDidLoad {
[super viewDidLoad]; self.tableView.rowHeight = ;
[self.tableView registerClass:[UserCell class] forCellReuseIdentifier:NSStringFromClass([UserCell class])]; @weakify(self); self.title = NSLocalizedString(@"Random Users", nil); UIBarButtonItem *clearImageCacheBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Clear Cache", nil) style:UIBarButtonItemStylePlain target:nil action:nil];
clearImageCacheBarButtonItem.rac_command = self.viewModel.clearImageCacheCommand;
self.navigationItem.rightBarButtonItem = clearImageCacheBarButtonItem; self.refreshControl = [[UIRefreshControl alloc] init];
[[[self.refreshControl rac_signalForControlEvents:UIControlEventValueChanged]
mapReplace:self.viewModel.userViewModelsCommand]
subscribeNext:^(RACCommand *userViewModelsCommand) {
[userViewModelsCommand execute:nil];
}]; [RACObserve(self.viewModel, loading)
subscribeNext:^(NSNumber *loading) {
@strongify(self);
if ([loading boolValue]) {
[self.refreshControl beginRefreshing];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
} else {
[self.refreshControl endRefreshing];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
}]; [[RACObserve(self.viewModel, userViewModels)
ignore:nil]
subscribeNext:^(id _) {
@strongify(self);
[self.tableView reloadData];
}]; [self.viewModel.userViewModelsCommand execute:nil];
} #pragma mark UITableViewDataSource - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return ;
} - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.viewModel.userViewModels count];
} - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UserViewModel *viewModel = self.viewModel.userViewModels[indexPath.row]; UserCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([UserCell class]) forIndexPath:indexPath];
cell.viewModel = viewModel;
cell.viewModel.active = YES;
return cell;
} # pragma mark UITableViewDelegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UserViewModel *userViewModel = self.viewModel.userViewModels[indexPath.row];
NSLog(@"Selected: %@", userViewModel);
[tableView deselectRowAtIndexPath:indexPath animated:YES];
} - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { } - (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
UserCell *userCell = (UserCell *)cell;
userCell.viewModel.active = NO;
} @end
6:UserCell代码:
@class UserViewModel; #pragma mark - @interface UserCell : UITableViewCell @property (nonatomic) UserViewModel *viewModel; @end
#import "UserCell.h" #import "ImageView.h" #import "UserViewModel.h"
#import "ImageViewModel.h" #import <ReactiveCocoa/ReactiveCocoa.h> #pragma mark - @interface UserCell () @property (nonatomic, readonly) ImageView *avatarImageView; @end @implementation UserCell - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self != nil) {
_avatarImageView = [[ImageView alloc] init];
[self.contentView addSubview:_avatarImageView];
}
return self;
} - (void)setViewModel:(UserViewModel *)viewModel {
if (_viewModel == viewModel) return; _viewModel = viewModel; self.avatarImageView.viewModel = _viewModel.imageViewModel;
self.textLabel.text = _viewModel.name;
} - (void)layoutSubviews {
[super layoutSubviews]; self.avatarImageView.frame = CGRectMake(, , , );
self.textLabel.frame = CGRectMake(, , , );
} @end
7:调用主控制器跳转
UsersViewModel *usersViewModel = [[UsersViewModel alloc] init];
UsersViewController *usersViewController = [[UsersViewController alloc] initWithViewModel:usersViewModel];
另:reactivecocoa afnetworking地交互可以查下面这个实例,地址:https://github.com/octokit/octokit.objc
小项目框架设计(ReactiveCocoa+MVVM+AFNetworking+FMDB) 地址:http://www.tuicool.com/articles/Q3uuQvA
ReactiveCocoa框架下的MVVM模式解读的更多相关文章
- 【转】ASP.NET MVC框架下使用MVVM模式-KnockOutJS+JQ模板例子
KnockOutJS学习系列----(一) 好几个月没去写博客了,最近也是因为项目紧张,不过这个不是借口,J. 很多时候可能是因为事情一多,然后没法静下来心来去写点东西,学点东西. 也很抱歉,突然看到 ...
- 【工作笔记二】ASP.NET MVC框架下使用MVVM模式
ASP.NET MVC框架下使用MVVM模式 原文:http://www.cnblogs.com/n-pei/archive/2011/07/21/2113022.html 对于asp.net mvc ...
- WPF Prism框架下基于MVVM模式的命令、绑定、事件
Prism框架下的自定义路由事件和命令绑定 BaseCode XAML代码: <Button x:Class="IM.UI.CommandEx.PrismCommandEx" ...
- 由项目浅谈JS中MVVM模式
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1. 背景 最近项目原因使用了durandal.js和knock ...
- angular中的MVVM模式
在开始介绍angular原理之前,我们有必要先了解下mvvm模式在angular中运用.虽然在angular社区一直将angular统称为前端MVC框架,同时angular团队也称它为MVW(What ...
- MVVM模式应用体会
转自:http://www.cnblogs.com/626498301/archive/2011/04/08/2009404.html 进公司实习工作后,本人接触的第一个技术名语就是MVVM模式,从学 ...
- js架构设计模式——由项目浅谈JS中MVVM模式
1. 背景 最近项目原因使用了durandal.js和knockout.js,颇有受益.决定写一个比较浅显的总结. 之前一直在用SpringMVC框架写后台,前台是用JSP+JS+标签库,算是很 ...
- 前端笔记之微信小程序(二){{}}插值和MVVM模式&数据双向绑定&指令&API
一.双花括号{{}}插值和MVVM模式 1.1 体会{{}}插值 index.wxml的标签不是html的那些标签,这里的view就是div. {{}}这样的插值写法,叫做mustache语法.mus ...
- iOS开发之ReactiveCocoa下的MVVM(干货分享)
最近工作比较忙,但还是出来更新博客了,今天给大家分享一些ReactiveCocoa以及MVVM的一些东西,干活还是比较足的.在之前发表过一篇博文,名字叫做<iOS开发之浅谈MVVM的架构设计与团 ...
随机推荐
- Javascript 布尔操作符总结
在一门编程语言中,布尔操作符的重要性堪比相等操作符.如果没有测试两个值关系的能力,那么诸如if...else和循环之类的语句就不会有用武之地了.在像javascript这样弱类型语言更有其妙用,让我们 ...
- 网络基础:NetBIOS
网络基础小补. 利用 NetBIOS 名称与其他计算机通信 网络中的计算机之间必须知道IP地址后才能相互通信.但对人来说IP难以记忆,NetBIOS计算机名称比较容易记忆.当计算机使用 NetBIOS ...
- C#基础04
介绍:泛型介绍,索引,Foreach遍历的解释,yield方法,path文件操作,Directory类基本操作<目录> 一:泛型 百度资料:泛型是 2.0 版 C# 语言和公共语言运行 ...
- C#实现网页爬虫
HTTP请求工具类(功能:1.获取网页html:2.下载网络图片:): using System; using System.Collections.Generic; using System.Dra ...
- 基于cookie实现zTree树刷新后,展开状态不变
1.除了引用jQuery和zTree的JS外,引用cookie的JS: <script type="text/javascript" src="~/Scripts/ ...
- 应用Css美化表单
原来的效果 美化之后的效果 实现代码 <style> .container { margin:0auto; width:620px; } fieldset { padding:18px ...
- 做10年Windows程序员与做10年Linux程序员的区别
如果一个程序员从来没有在linux,unix下开发过程序,一直在windows下面开发程序, 同样是工作10年, 大部分情况下与在linux,unix下面开发10年的程序员水平会差别很大.我写这篇文章 ...
- 说说这篇「我为什么从python转向go
作者 CMGS2015.05.17 15:47* 写了7891字,被143人关注,获得了97个喜欢 说说这篇「我为什么从python转向go」 字数3748 阅读24227 评论21 喜欢81 恩看了 ...
- Redis配置集群二(window)
第一篇那redis的基础命令都差不多讲了一遍了,这篇就将怎么配置集群了,最后要达到的效果是一台主redis,还有几台从的redis,每次数据都是同步的,当主redis挂掉了,那么就会从几台从redis ...
- hdu-1213-How Many Tables
How Many Tables Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...