//plupload 集成
Ext.define('ux.plup.File', {
extend: 'Ext.form.field.Text',
xtype: 'plupFile',
alias: ['widget.plupFile'],
requires: ['Ext.form.trigger.Component', 'Ext.button.Button', 'Ext.window.Toast'],
//plup对象
uploader: null,
//上传文件最大数量限制,最小只能设置为1
maxFileCount: 1,
//是否单文件上传,结合FileList使用时必须设置为false,否则不会有预览效果
onlyOne: true,
//上传地址,必须
url: 'upload.php',
//上传控件配置
pluploadConfig: {
//url 服务器端的上传页面地址,必须指定
//swf文件,当需要使用swf方式进行上传时需要配置该参数,必须指定
flash_swf_url: 'app/js/plupload/js/Moxie.swf',
//用来指定上传方式,指定多个上传方式请使用逗号隔开。一般情况下,你不需要配置该参数,因为Plupload默认会根据你的其他的参数配置来选择最合适的上传方式。如果没有特殊要求的话,Plupload会首先选择html5上传方式,如果浏览器不支持html5,则会使用flash或silverlight,如果前面两者也都不支持,则会使用最传统的html4上传方式。如果你想指定使用某个上传方式,或改变上传方式的优先顺序,则你可以配置该参数。
//html5,flash,silverlight,html4
runtimes: 'html5,flash,html4',
// 可以使用该参数来限制上传文件的类型,大小等,该参数以对象的形式传入,它包括三个属性:
filters: {
//mime_types:用来限定上传文件的类型,为一个数组,该数组的每个元素又是一个对象,该对象有title和extensions两个属性,title为该过滤器的名称,extensions为文件扩展名,有多个时用逗号隔开。该属性默认为一个空数组,即不做限制。
//max_file_size:用来限定上传文件的大小,如果文件体积超过了该值,则不能被选取。值可以为一个数字,单位为b,也可以是一个字符串,由数字和单位组成,如'200kb'
//prevent_duplicates:是否允许选取重复的文件,为true时表示不允许,为false时表示允许,默认为false。如果两个文件的文件名和大小都相同,则会被认为是重复的文件
prevent_duplicates: true
}
// multi_selection:是否可以在文件浏览对话框中选择多个文件,true为可以,false为不可以。默认true,即可以选择多个文件。需要注意的是,在某些不支持多选文件的环境中,默认值是false。比如在ios7的safari浏览器中,由于存在bug,造成不能多选文件。当然,在html4上传方式中,也是无法多选文件的。
},
/**
* @cfg {String} emptyText
* Overridden to undefined as {@link #emptyText} is not supported with {@link #inputType inputType}:'file' and should be avoided.
* The default text to place into an empty field.
*/
emptyText: undefined, needArrowKeys: false, triggers: {
//禁用时显示的按钮
//因为上传按钮禁用效果无效,所以在禁用时显示另外一个按钮
//这样就可以避免禁用按钮失效的bug
disableButton: {
type: 'component',
hideOnReadOnly: false,
hidden: true,
// Most form fields prevent the default browser action on mousedown of the trigger.
// This is intended to prevent the field's input element from losing focus when
// the trigger is clicked. File fields disable this behavior because:
// 1. The input element does not receive focus when the field is focused. The button does.
// 2. Preventing the default action of touchstart (translated from mousedown
// on mobile browsers) prevents the browser's file dialog from opening.
preventMouseDown: false
},
filebutton: {
type: 'component',
hideOnReadOnly: false,
// Most form fields prevent the default browser action on mousedown of the trigger.
// This is intended to prevent the field's input element from losing focus when
// the trigger is clicked. File fields disable this behavior because:
// 1. The input element does not receive focus when the field is focused. The button does.
// 2. Preventing the default action of touchstart (translated from mousedown
// on mobile browsers) prevents the browser's file dialog from opening.
preventMouseDown: false
}
}, //<locale>
/**
* @cfg {String} buttonText
* The button text to display on the upload button. Note that if you supply a value for
* {@link #buttonConfig}, the buttonConfig.text value will be used instead if available.
*/
buttonText: '选择文件',
//</locale>
/**
* @cfg {Boolean} buttonOnly
* True to display the file upload field as a button with no visible text field. If true, all
* inherited Text members will still be available.
*/
buttonOnly: false, /**
* @cfg {Number} buttonMargin
* The number of pixels of space reserved between the button and the text field. Note that this only
* applies if {@link #buttonOnly} = false.
*/
buttonMargin: 3, /**
* @cfg {Boolean} clearOnSubmit
* 提交后清除值
*/
clearOnSubmit: true, /**
* @private
*/
extraFieldBodyCls: Ext.baseCSSPrefix + 'form-file-wrap', /**
* @private
*/
inputCls: Ext.baseCSSPrefix + 'form-text-file', /**
* @cfg {Boolean} [readOnly=true]
*只读,禁止修改
*/
readOnly: true, /**
* @cfg {Boolean} editable
* @inheritdoc
*/
editable: false,
//form表单中不提交值
submitValue: true, /**
* Do not show hand pointer over text field since file choose dialog is only shown when clicking in the button
* @private
*/
triggerNoEditCls: '', /**
* @private
* Extract the file element, button outer element, and button active element.
*/
childEls: ['browseButtonWrap'], /**
* @private 创建上传按钮
*/
applyTriggers: function (triggers) {
var me = this,
triggerCfg = (triggers || {}).filebutton,
disableCfg = triggers.disableButton;
//增加禁用按钮
if (disableCfg) {
disableCfg.component = Ext.apply({
xtype: 'button',
ownerCt: me,
id: me.id + '-disableButton',
ui: me.ui,
disabled: true,
text: me.buttonText
})
}
//增加上传按钮
if (triggerCfg) {
triggerCfg.component = Ext.apply({
xtype: 'button',
ownerCt: me,
id: me.id + '-button',
ui: me.ui,
disabled: me.disabled,
text: me.buttonText,
//设置margin-left
style: me.buttonOnly ? '' : me.getButtonMarginProp() + me.buttonMargin + 'px',
listeners: {
scope: me,
render: me.createPlup
}
},
me.buttonConfig); return me.callParent([triggers]);
}
// <debug>
else {
Ext.raise(me.$className + ' requires a valid trigger config containing "button" specification');
}
// </debug>
}, /**
* @private
*/
onRender: function () {
var me = this,
inputEl, button, buttonEl, trigger; me.callParent(arguments); inputEl = me.inputEl;
//它不应该有name
inputEl.dom.name = ''; //有些浏览器会显示在该领域的闪烁的光标,即使它是只读的。如果我们有这样的事情
//获得焦点,就转发给我们focusEl。还注意到,在IE中,文件输入作为处理
//2元素Tab键的目的(文本,然后按钮)。所以,当你通过TAB键,这将需要2
//标签才能到下一个字段。据我知道有没有办法解决这个在任何一种合理的方式。
inputEl.on('focus', me.onInputFocus, me);
inputEl.on('mousedown', me.onInputMouseDown, me);
//获取上传按钮
trigger = me.getTrigger('filebutton');
button = me.button = trigger.component;
buttonEl = button.el;
if (me.buttonOnly) {
me.inputWrap.setDisplayed(false);
me.shrinkWrap = 3;
} // Ensure the trigger element is sized correctly upon render
trigger.el.setWidth(buttonEl.getWidth() + buttonEl.getMargin('lr'));
if (Ext.isIE) {
me.button.getEl().repaint();
}
},
/**
* Gets the markup to be inserted into the subTplMarkup.
*/
getTriggerMarkup: function () {
console.log('getTriggerMarkup');
return '<td id="' + this.id + '-browseButtonWrap" data-ref="browseButtonWrap" role="presentation"></td>';
},
onShow: function () {
this.callParent();
//如果我们开始了隐藏,按钮可能有一个搞砸布局
//因为我们不像个容器
this.button.updateLayout();
},
//创建上传控件
createPlup: function (btn) {
var me = this,
//上传配置
config = me.pluploadConfig,
//name值
name = me.getName(),
//设置上传地址
url = me.url,
uploader;
//获取当前按钮id
config.browse_button = btn.getId();
//指定文件上传时文件域的名称,默认为file,例如在php中你可以使用$_FILES['file']来获取上传的文件信息
if (name) {
config.file_data_name = name;
}
if (url) {
config.url = url;
}
//上传文件最大数量限制为1时,选择文件只能选择一个
if (me.maxFileCount === 1) {
config.multi_selection = false;
} //创建上传对象
uploader = me.uploader = new plupload.Uploader(config);
//初始化
uploader.init();
//监听错误文件被添加到上传队列时
uploader.bind('FilesAdded',
function (uploader, files) {
me.filesAdded(uploader, files);
});
//监听错误
//-602 重复文件
uploader.bind('Error',
function (uploader, file) {
var code = file.code;
if (code === -200) {
//上传失败
me.loadedFailure(uploader, {
message: file.message
});
} else {
//抛出内部错误
me.markInvalid(file.message);
}
});
//上传完成
uploader.bind('FileUploaded',
function (loader, file, response) {
response = Ext.decode(response.response);
if (response.success) {
//上传成功
me.loadedSuccess(response);
} else {
//上传失败
me.loadedFailure(loader, response);
}
});
//会在文件上传过程中不断触发,可以用此事件来显示上传进度
uploader.bind('UploadProgress',
function (loader, file) {
Ext.Msg.updateProgress(loader.total.percent / 100, loader.total.percent + '%', '正在上传:' + file.name);
//console.log(loader.total.percent);
if (loader.total.percent == 100) {
Ext.Msg.wait('上传成功,正在处理数据...','上传文件');
}
});
},
//文件被添加到上传队列
//uploader 上传对象
//files 当前选中文件组
filesAdded: function (uploader, files) {
var me = this,
//上传文件最大数量限制
maxFileCount = me.maxFileCount,
//现有文件(包括新选择的文件)
oldFiles = uploader.files,
//现有文件总数
length = oldFiles.length,
i, count; //上传文件最大数量限制为1,并且onlyOne为true时
if (maxFileCount === 1 && me.onlyOne) {
length = length - 2;
//移除除最新文件之外所有文件
for (i = length; i >= 0; i--) {
uploader.removeFile(oldFiles[i]);
}
//设置文本框显示值
me.setValue(oldFiles[0].name);
} else {
//文件数量超过或等于最大限制,禁用文件选择
if (length >= maxFileCount) {
count = length - maxFileCount;
//从files中移除多于最大数量限制的文件,从最新选择的文件开始移除
for (i = 0; i < count; i++) {
files.pop();
}
me.onDisable();
}
length = length - 1;
maxFileCount = maxFileCount - 1;
//移除多于最大数量限制的文件,从最新选择的文件开始移除
for (i = length; i > maxFileCount; i--) {
uploader.removeFile(oldFiles[i]);
}
//设置文本框显示值
me.setValue(files[0].name);
//抛出事件,供FileList使用
me.fireEvent('addField', files);
}
},
//移除文件
removeFile: function (file) {
var me = this,
uploader = me.uploader,
files;
//移除文件
uploader.removeFile(file);
files = uploader.files;
//取消禁用
me.onEnable();
//设置文本框的值
if (uploader.files.length <= 0) {
me.setValue(null);
} else {
me.setValue(files[0].name);
}
},
submit: function (params) {
var me = this,
url = params.url,
waitMsg = params.waitMsg || '正在上传',
optionParams = params.params,
uploader = me.uploader;
//设置上传地址
if (url) {
uploader.setOption('url', url);
}
//设置参数
if (optionParams) {
uploader.setOption('multipart_params', optionParams);
}
//上传成功执行方法
me.success = params.success || Ext.emptyFn;
//上传失败执行方法
me.failure = params.failure || Ext.emptyFn;
uploader.start();
Ext.Msg.progress('上传文件', waitMsg);
},
//上传成功
loadedSuccess: function (response) {
Ext.MessageBox.hide();
this.reset();
//抛出事件
this.fireEvent('loadedSuccess', this);
//执行成功函数
this.success(response);
},
//上传失败
loadedFailure: function (loader, response) {
//停止上传
loader.stop();
//隐藏进度条
Ext.MessageBox.hide();
//重置
this.reset();
//抛出事件
this.fireEvent('loadedFailure', this);
//执行失败函数
this.failure(response);
},
//上传成功执行,submit方法回调
success: Ext.emptyFn,
//上传失败执行,submit方法回调
failure: Ext.emptyFn,
//重置上传控件
reset: function () {
var uploader = this.uploader,
files = uploader.files,
//现有文件总数
length = files.length - 1,
i;
//移除所有文件
for (i = length; i > -1; i--) {
uploader.removeFile(files[i]);
}
this.onEnable();
this.callParent();
},
//禁用控件tab键切换功能
getSubTplData: function (fieldData) {
var data = this.callParent([fieldData]);
//因为它是上传控件不应该获取焦点;
//然而input元素自然是可聚焦,所以我们必须
//由它的tabIndex设置为-1停用。
data.tabIdx = -1; return data;
},
//禁用
onDisable: function () {
this.callParent();
this.setFileEnable(true);
},
//取消禁用
onEnable: function () {
this.callParent();
this.setFileEnable(false);
},
//更改禁用状态
setFileEnable: function (is) {
var me = this;
//设置上传控件是否禁用
//某些情况下设置会失效,原因不明
me.uploader.disableBrowse(is);
//当上传按钮隐藏时显示一个假按钮
//上传按启用时隐藏加按钮
//这个解决方案是为了避免上面说的禁用失效问题
me.getTrigger('disableButton').setHidden(!is);
me.getTrigger('filebutton').setHidden(is);
//重绘布局
me.updateLayout();
},
//销毁
onDestroy: function () {
this.uploader.destroy();
this.callParent();
},
restoreInput: function (el) {
//如果我们不渲染,我们不需要做任何事情,它会创建
//当我们刷新到DOM。
if (this.rendered) {
var button = this.button;
button.restoreInput(el);
this.fileInputEl = button.fileInputEl;
}
},
getButtonMarginProp: function () {
return 'margin-left:';
},
//输入框获得焦点
onInputFocus: function () {
this.focus();
//从只读输入元素切换焦点文件输入
//结果在文件输入的不正确的定位。
//添加和删除位置:相对有助于解决这个问题。
//见https://sencha.jira.com/browse/EXTJS-18933
if (Ext.isIE9m) {
this.fileInputEl.addCls(Ext.baseCSSPrefix + 'position-relative');
this.fileInputEl.removeCls(Ext.baseCSSPrefix + 'position-relative');
}
},
//点击输入框
onInputMouseDown: function (e) {
//console.log('onInputMouseDown');
//有些浏览器将显示即使输入是只读的光标,
//这将在inputEl之间聚焦随后的聚焦跳跃的短瞬间
//和文件按钮是可见的。
//从闪烁的重点消除防止inputEl。
e.preventDefault(); this.focus();
},
privates: {
getFocusEl: function () {
return this.button;
}, getFocusClsEl: Ext.privateFn
}
});

用法等同form.submit()方法,获取控件后plupFile.submit()即可提交,可能有坑

 //自定义批量上传预览控件
//isUpload为true时每选择一个文件都会触发onAddField事件,需要自行处理上传,多用于修改场景
//isUpload为false时每选择一个文件都会在本地自增file控件,最后在表单中手动批量提交
Ext.define('ux.plup.FileList', {
extend: 'Ext.container.Container',
alias: ['widget.plupFileList'],
requires: ['Ext.DataView', 'ux.plup.File'],
//样式
cls: 'uxFileList',
config: {
//数据
data: null,
//预览视图
dataview: {
itemTpl: new Ext.XTemplate('<div class="thumb-wrap bb" style="background-image:url({img});">', '<button type="button" class="x-fa fa-trash"></button>', '</div>', '<p>{name}</p>')
},
//上传控件配置
uploaderField: {
onlyOne: false,
buttonOnly: true,
//提交后清除
clearOnSubmit: false,
fieldLabel: '上传文件',
msgTarget: 'under'
},
//uploader配置
pluploadConfig:null
},
//是否立即上传
isUpload: false,
//是否只能查看
isSee: false,
//当前文件总数
fieldCount:0,
//上传文件数量限制,默认一个
maxFileCount: 1,
//默认预览图片路径,上传文件非图片时使用
preview: {
//文件
file: 'classic/resources/images/file.png',
//视频
video: 'classic/resources/images/video.jpg'
},
//初始化
initComponent: function () {
var me = this;
me.callParent(arguments);
//新增上传控件、图片列表
me.add([me.getUploaderField(), me.getDataview()]);
},
//设置isSee
setIsSee: function (isSee) {
this.isSee = isSee;
},
//设置isUpload
setIsUpload: function (isUpload) {
this.isUpload = isUpload;
},
/*创建上传控件*/
applyUploaderField: function (config) {
config.maxFileCount = this.maxFileCount;
return Ext.factory(config, ux.plup.File, this.getUploaderField());
},
/*更新上传控件*/
updateUploaderField: function (newItem) {
if (newItem) {
//监听上传控件
newItem.on({
scope: this,
addField: 'onAddField',
loadedFailure: 'removeAll'
});
}
},
//更新上传控件配置
updatePluploadConfig: function (option) {
if (option) {
var uploaderField = this.getUploaderField(),
uploader = uploaderField.uploader;
uploader.setOption(option);
uploaderField.reset();
this.removeAll();
}
},
//选择文件完成
onAddField: function (files) {
var me = this,
length = files.length,
i;
if (me.isUpload) {
//抛出事件
me.fireEvent('onAddField', me, files);
} else {
//添加预览图片
for (i = 0; i < length; i++) {
me.previewImage(files[i], function (file, src) {
me.addData({
//预览图片
img: src,
//文件名称
name: file.name,
file: file
});
})
}
}
},
//获取上传文件预览图
//plupload中为我们提供了mOxie对象
//有关mOxie的介绍和说明请看:https://github.com/moxiecode/moxie/wiki/API
previewImage: function (file, callback) {
//如果不是图片,返回默认预览图
if (!file || !/image\//.test(file.type)) {
var url = this.preview.file;
//如果是视频格式
if (/video\//.test(file.type)) {
url = this.preview.video;
}
callback && callback(file, url);
};
//确保文件是图片
if (file.type === 'image/gif') {
//gif使用FileReader进行预览,因为mOxie.Image只支持jpg和png
var fr = new mOxie.FileReader();
fr.onload = function () {
callback && callback(file, fr.result);
fr.destroy();
fr = null;
}
fr.readAsDataURL(file.getSource());
} else {
var preloader = new mOxie.Image();
preloader.onload = function () {
////先压缩一下要预览的图片,宽300,高300
//preloader.downsize(300, 300);
var imgsrc = preloader.type == 'image/jpeg' ? preloader.getAsDataURL('image/jpeg', 80) : preloader.getAsDataURL(); //得到图片src,实质为一个base64编码的数据
callback && callback(file, imgsrc); //callback传入的参数为预览图片的url
preloader.destroy();
preloader = null;
};
preloader.load(file.getSource());
}
},
/*创建图片列表*/
applyDataview: function (config) {
return Ext.factory(config, Ext.DataView, this.getDataview());
},
/* 更新图片列表*/
updateDataview: function (newItem) {
if (newItem) {
//监听预览列表
newItem.on({
itemclick: 'itemclick',
itemdblclick: 'itemdblclick',
scope: this
});
}
},
//单击删除
itemclick: function (t, record, item, index, e) {
var me = this,
store = t.getStore();
//点击删除按钮才执行
if (!me.isSee && e.target.tagName === 'BUTTON') {
Ext.MessageBox.confirm('删除确认', '确认删除?',
function (btnText) {
if (btnText === 'yes') {
me.removeFile(me, store, record);
}
}, me);
}
},
//双击触发事件
itemdblclick: function (t, record, item, index, e) {
var me = this;
if (e.target.tagName !== 'BUTTON') {
me.fireEvent('onItemDbClick', me, record);
}
},
//新增图片
addData: function (data) {
var me = this,
store = me.getStore(), //获取最大限制
maxFileCount = me.maxFileCount;
if (store && store.storeId !== 'ext-empty-store') {
//已有数据,新增
store.add(data);
if (!data.file) {
//检测数目
me.fieldCount = me.fieldCount || 0;
//总数加1
me.fieldCount++;
//如果达到最大限制禁用
if (me.fieldCount >= maxFileCount) {
me.onDisable();
}
me.setValue(data.name);
}
} else {
//没有数据,创建
me.setData([data]);
}
},
/*创建data*/
applyData: function (data) {
return data;
},
/*更新data*/
updateData: function (data) {
if (data && data.length > 0) {
//有数据则创建store
var me = this,
dataview = me.getDataview(),
//获取最大限制
maxFileCount = me.maxFileCount;
dataview.setStore(Ext.create('Ext.data.Store', {
data: data,
autoDestroy: true
}));
me.fieldCount = data.length;
//如果达到最大限制禁用
if (me.fieldCount >= maxFileCount) {
me.onDisable();
}
me.setValue(data[0].name);
}
},
//获取所有数据
getStore: function () {
return this.getDataview().getStore();
},
//清除所有数据
removeAll: function () {
var store = this.getStore();
if (store) {
store.removeAll();
}
},
//移除单个文件
removeFile: function (me, store, record) {
var file = record.get('file'),
uploaderField = this.getUploaderField();
if (file) {
uploaderField.removeFile(record.get('file'));
} else {
me.onEnable();
}
me.fieldCount--;
store.remove(record);
if (me.fieldCount<=0) {
uploaderField.setValue(null);
} else {
uploaderField.setValue(store.getAt(0).get('name'));
}
},
//上传附件
submit: function (params) {
this.getUploaderField().submit(params);
},
//禁用
onDisable: function () {
var file = this.getUploaderField();
file.onDisable();
},
//取消禁用
onEnable: function () {
this.getUploaderField().onEnable();
},
//设置文本框的值
setValue: function (value) {
this.getUploaderField().setValue(value);
} });

ux.plup.File plupload 集成 ux.plup.FileLis 批量上传预览的更多相关文章

  1. input file图片上传预览

    两种方法,方法一: js代码: //头像上传预览 $("#up").change(function() { var $file = $(this); var fileObj = $ ...

  2. input file图片上传预览效果

    两种方法,方法一: js代码: //头像上传预览 $("#up").change(function() { var $file = $(this); var fileObj = $ ...

  3. 用file标签实现多图文件上传预览

    效果图: js 代码: <script> //下面用于多图片上传预览功能 function setImagePreviews(avalue) { var docObj = document ...

  4. html,图片上传预览,input file获取文件等相关操作

    input file常用方法: var obj=document.getElementById("upimage"); var file=obj.files[0];//获取文件数据 ...

  5. input[type=file]样式更改以及图片上传预览

    以前知道input[type=file]可以上传文件,但是没用过,今天初次用,总感觉默认样式怪怪的,想修改一下,于是折腾了半天,总算是小有收获. 以上是默认样式,这里我想小小的修改下: HTML代码如 ...

  6. WEB版一次选择多个文件进行批量上传(Plupload)的解决方案

    WEB版一次选择多个文件进行批量上传(Plupload)的解决方案  转载自http://www.cnblogs.com/chillsrc/archive/2013/01/30/2883648.htm ...

  7. 定制jQuery File Upload为微博式单文件上传

    日志未经声明,均为AlloVince原创.版权采用『 知识共享署名-非商业性使用 2.5 许可协议』进行许可. jQuery File Upload是一个非常优秀的上传组件,主要使用了XHR作为上传方 ...

  8. plupload批量上传分片(后台代码)

    plupload批量上传分片功能, 对于文件比较大的情况下,plupload支持分片上传,后台代码如下: /** * * 方法:upLoadSpecialProgramPictrue * 方法说明:本 ...

  9. 【全网首创】修改 Ext.ux.UploadDialog.Dialog 源码支持多选添加文件,批量上传文件

    公司老框架的一个页面需要用到文件上传,本以为修改一个配置参数即可解决,百度一番发现都在说这个第三方插件不支持文件多选功能,还有各种各样缺点,暂且不讨论这些吧.先完成领导安排下来的任务. 任务一:支持多 ...

随机推荐

  1. spring三种实例化bean的方式

    1构造函数实例化 2静态工厂方法实例化 3实例工厂方法实例化 service接口: package service; public interface PersonService { public v ...

  2. paip。java 高级特性 类默认方法,匿名方法+多方法连续调用, 常量类型

    paip.java 高级特性 类默认方法,匿名方法+多方法连续调用, 常量类型 作者Attilax 艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http ...

  3. iOS开发---iPhone SDK 包含哪些东西?

    第一部分: 在使用Intel芯片的Macintosh计算机开发iOS应用程序所需的全部接口.工具以及资源全都包含于iPhone SDK. 苹果公司将大部分系统接口发布在框架这种特殊的数据包.一个框架就 ...

  4. Java thread jargon

    In Java thread topic, the task to be executed and the thread to drive the task are two concepts shou ...

  5. 深入学习系列--Data Structure--02字符串

    字符串可以说是我们实际工作中使用最多的数据类型了,常见的字符串操作包括链接.取子串.格式化等.这部分内容总体来说比较容易理解,最难的部分要数字符串的模式匹配方法了,尤其是KMP算法,需要通过实践加以记 ...

  6. c#之第三课

    学习获取终端输入的参数并且打印,以及使用循环. using System; public class CommandLine { public static void Main(string[] ar ...

  7. 高端PCB设计相关知识整理

    PCB的设计布局布线实际上是一门很复杂而且大部分靠经验来做的学问,很多东西也有点玄乎,但有很多经验性的结论和公式还是可以参考的 保证原创,一天不一定写的完 CH.1 更加严重的电磁干扰 首先基本上微电 ...

  8. Zookeeper开源客户端框架Curator简介[转]

    Curator是Netflix开源的一套ZooKeeper客户端框架. Netflix在使用ZooKeeper的过程中发现ZooKeeper自带的客户端太底层, 应用方在使用的时候需要自己处理很多事情 ...

  9. 跨平台web调试代理工具---whistle

    whistle是基于Node实现的跨平台web调试代理工具,支持windows.mac.linux等所有安装了Node的操作系统,可以部署在本地机器.虚拟机或远程服务器,并通过本地网页查看或修改HTT ...

  10. 【Cocos2d-x】VS2012开发2dx无法解析的外部符号解决记录(第一篇)【转】

    come from http://acoder.me/cocos2d-unresolved-external-symbol.html 看到cocos2d-x带了扩展包,心动的想尝试下,以下分享下我使用 ...