[转载]第一天:初识kissy—15天学会kissy | ria之家--RIA三部曲:jquery、ext、flex

mikel阅读(998)

[转载]第一天:初识kissy—15天学会kissy | ria之家–RIA三部曲:jquery、ext、flex.

第一天:初识kissy—15天学会kissy

一、什么是kissy?

  • 首先,kissy是一个由国人开发并开源的js框架;
  • 其次,kissy是一个非常容易上手的js框架;
  • 再次,kissy是一个巧灵活、简洁实用的js框架;
  • 最后,kissy是一个融合了YUI3先进编程思想和JQuery巧妙API设计思想的js框架。

kissy由淘宝UED开发和维护,代码质量和更新速度都有保证,可以大胆的在项目中使用。

kissy很容易上手,同时可以大大提高你的前端开发效率!

kissy虽然有API文档,但是没有一个完整的上手指南,单纯对着索然无味的API文档,学习兴致自然大减,这就是为什么明河写此系列教程的原因,明河不会对所有API进行讲解,只是通过更友好的说明和更形象的实例,引领朋友进入kissy的世界。

在明河发布此系列教程前,正好kissy更新到1.15(最新的稳定版,建议使用),教程的讲解也是针对1.15版展开。

二、kissy适合的人群

  • 1、厌倦在一堆英文文档上找答案;
  • 2、向往敏捷开发前端之道;
  • 3、有js基础,至少了解js面向对象的写法;
  • 4、最好有用过类似JQuery、YUI或ext等类库,上手会更快;

三、学习kissy前的准备

四、关于kissy的介绍视频

五、kissy源代码包目录说明

1、kissy的下载:

进入http://github.com/kissyteam/kissy,然后点击左上角的下载按钮:

(git默认语言为英文,你可以点击头部的切换语言按钮,转成中文。)

2、完整的kissy代码包结构:

  • build: 构建好的发布文件
  • docs: API 文档
  • src: 源码、测试等开发资源
  • third-party: 第三方库
  • tools: 打包压缩等自动化工具

六、kissy的代码结构

1、kissy的项目总览:

上图来自拔赤大大的kissy简介

2、kissy核心代码结构:

上图来自玉伯大大的Into to KISSY

七、明河结语

以上内容也颇为丰富,不必一一细看,通览即可,关键是对kissy有个总体的印象。

直到现在明河还未写一行kissy代码,别急,好戏,接下来才开始!

[转载]淘宝Kissy框架分析【六】 - BlueDream - 博客园

mikel阅读(963)

[转载]淘宝Kissy框架分析【六】 – BlueDream – 博客园.

现在开始分析kissy-ua.js 浏览器检测部分.

源码如下:

复制代码
/**
* @module    j1616-ua
* @author    liangchaoyjs@163.com
*/
J1616.add(
j1616-uafunction(J) {
var ua = navigator.userAgent,
m,
= {
webkit: 
0,
chrome: 
0,
safari: 
0,
gecko: 
0,
firefox: 
0,
ie: 
0,
opera: 
0,
mobile: 

},
numberify 
= function(s) {
var c = 0;
return parseFloat(s.replace(/\./g, function() {
return (c++ === 0? . : ;
}));
};

// WebKit
    if ((m = ua.match(/AppleWebKit\/([\d.]*)/)) && m[1]) {
        o.webkit = numberify(m[1]);

// Chrome
        if ((m = ua.match(/Chrome\/([\d.]*)/)) && m[1]) {
            o.chrome = numberify(m[1]);
}

// Safari
        if ((m = ua.match(/\/([\d.]*) Safari/)) && m[1]) {
            o.safari = numberify(m[1]);
}

// Apple Mobile
        if (/ Mobile\//.test(ua)) {
            o.mobile = Apple// iPad, iPhone or iPod Touch
        }
// Other WebKit Mobile Browsers
        else if ((m = ua.match(/NokiaN[^\/]*|Android \d\.\d|webOS\/\d\.\d/))) {
o.mobile 
= m[0]; // Nokia N-series, Android, webOS, ex:NokiaN95
        }
}
// NOT WebKit
    else {
// Opera
        if ((m = ua.match(/Opera\/.* Version\/([\d.]*)/)) && m[1]) {
o.opera 
= numberify(m[1]);

// Opera Mini
            if ((ua.match(/Opera Mini[^;]*/))) {
o.mobile 
= m[0]; // ex: Opera Mini/2.0.4509/1316
            }
// NOT WebKit or Opera    
        } else {
// MSIE
            if ((m = ua.match(/MSIE\s([^;]*)/)) && m[1]) {
o.ie 
= numberify(m[1]);

// NOT WebKit, Opera or IE
            } else {
// Gecko
                if ((m = ua.match(/Gecko/))) {
o.gecko 
= 1;
if ((m = ua.match(/rv:([\d.]*)/)) && m[1]) {
o.gecko 
= numberify(m[1]);
}

// Firefox
                    if ((m = ua.match(/Firefox\/([\d.]*)/)) && m[1]) {
                        o.firefox = numberify(m[1]);
}
}
}
}
}
J.UA 
= o;
});

复制代码

这里不会源码做剖析,因为都是比较容易理解. 但现在对于UA浏览器嗅探和特性检测(如JQuery)的孰优孰劣.我认为都有其合适的应用场景.看自己的需求吧.如果需要特性检测可以参考JQuery源码.

 

用法:

复制代码
(function(J) {
document.write(J.UA.ie 
+ <br/>) ;
document.write(J.UA.firefox 
+ <br/>);
document.write(J.UA.chrome 
+ <br/>);
document.write(J.UA.opera 
+ <br/>);
document.write(J.UA.safari 
+ <br/>);

})(J1616);

复制代码

如果是目标浏览器那么会返回该浏览器的版本号.如果不是那么就返回0。

比如.你想检测浏览器是不是IE并且是IE8 就可以写 J.UA.ie && J.UA.ie === 8.

 

关于浏览器各大排版引擎的介绍可参考这篇文章.

至此.整个kissy文件夹的3个.js文件都分析完毕了. 接着改啃比较大块的dom文件夹了.fighting!

[转载]淘宝Kissy框架分析【五】 - BlueDream - 博客园

mikel阅读(881)

[转载]淘宝Kissy框架分析【五】 – BlueDream – 博客园.

继续分析kissy-lang.js

8.makeArray函数 

作用:转化类数组对象为真实的数组.

原理:主要需要处理的就是将NodeList转化成真实的数组. 在非IE浏览器都可以通过Array.prototype.slice.call(NodeList)来直接转换.但IE却不支持.

所以IE下只能降级到普通的方法转换.

测试用例:

复制代码
<div>1</div><div>2</div><div>3</div><div>4</div>
<script>
(
function(J) {
J.log(J.makeArray(
a)); // [‘a’]
    J.log(J.makeArray(function a() {})); // [‘a()’]
    J.log(J.makeArray([ab])); // [‘a’, ‘b’]
    J.log(J.makeArray(null)); // []

var odiv = document.getElementsByTagName(div);
J.log(J.makeArray(odiv)); 
// [‘divElement’, ‘divElement’, ‘divElement’, ‘divElement’]
})(J1616);
</script>
复制代码

9.filter函数 

作用:通过回调函数的条件过滤数组项.

测试用例:

复制代码
(function(J) {
J.log(J.filter([
1344534], function(item) {
return item > 10;  // 过滤大于10的数组项
    })); // [34, 45]
    J.log(J.filter([1344534], function(item, index) {
return index > 2;  // 过滤索引大于2的数组项
    })); // [3, 4]
})(J1616);
复制代码

10.param函数 

作用:将一个hash类型序列化成有效的url格式串形式.

测试用例:

复制代码
(function(J) {
// 普通字符串
    var url1 = {namej16age23sexmen};
J.log(J.param(url1)); 
// name=j16&age=23&sex=men

// 空字符串
    var url2 = {nameagesexmen};
J.log(J.param(url2)); 
// name=&age=&sex=men

// 数组类型字符串
    var url3 = {name: [j16kissy], age23sex: [womenmen]};
J.log(J.param(url3)); 
// name[]=j16&name[]=kissy&age=23&sex[]=women&sex[]=men

})(J1616);
复制代码

11.unparam函数 

作用:param函数的逆转换(将url序列成hash对象). 但由于国情的原因.并不是完全可逆的.decodeURIComponent只能处理UTF-8编码的的中文. 而不能处理gbk编码的中文.

12.later函数

作用: 延迟函数. 在指定的时间内 执行一段函数(setTimeout). 或者在指定的时间内 重复的执行一段函数(setInterval).

测试用例:

复制代码
(function(J) {
var i = 0;
var intervalRun = function(a, b, c) {
if (++>= 10) {
timer.cancel();
}
J.log(i 
+  times run\s params is:  + [a, b, c]);
};
// 每个1秒 调用intervalRun函数. 并传入参数. 超过10次便停止
var timer = J.later(intervalRun, 1000/*1s*/, true/*setInterval*/, null/*context*/, [
abc]);

var timeoutRun = function(param) {
J.log(the setTimeout param is:  + param);
};
// 1秒后 调用一次timeoutRun函数. 并传入参数
J.later(timeoutRun, 1000, false, null, 
setTimeout);
})(J1616);

复制代码

13.now函数

作用:返回当前时间戳.

注意: kissy使用比较普通的new Date().getTime(). 有的框架用了高级浏览器支持的Date.now() || +new Data(比如mootools)但这个无所谓.清晰性更重要.

14.globalEval函数

作用:在全局范围内执行代码

原理:kissy使用了script.text. 但貌似opera最新版本会有点问题. 全局执行代码有几个方法.具体可以参考司徒的这篇文章.

测试用例:

(function(J) {
var i = local;
J.globalEval(
var j = “global”);
})(J1616);
alert(j); 
// 由于globalEval函数可以冲破局部.所以可以得到j ==> global
alert(i); // 由于i在闭包内. 所以是局部的 无法取到 而报错

至此kiss-lang.js部分分解完毕.接下来的是kissy-ua.js.

[转载]淘宝Kissy框架分析【三】 - BlueDream - 博客园

mikel阅读(973)

[转载]淘宝Kissy框架分析【三】 – BlueDream – 博客园.

继续分析kissy.js

6.extend函数 

作用: 这个extend函数是kissy框架面向对象的核心.实现了继承机制.kissy的继承使用了 对象冒充 + 原型继承的混合模式.

原理:

复制代码
var OP = Object.prototype,
// O方法作用是 用一个壳包装函数. 让其原型引用到父类的的原型
    // 然后将这个原型再覆盖给子类的原型. 壳函数的好处就是 new的时候 省空间. 因为构造为空
    O = function (o) {
function F() {}
F.prototype 
= o;
return new F();
},
sp 
= s.prototype,
rp 
= O(sp);

r.prototype = rp;
// 因为原型被覆盖.所以原型的prototype指向了F 要修正回来
//
 具体constructor的原理可参考http://www.cnblogs.com/objectorl/archive/2009/09/02/1632715.html
rp.constructor = r;

// 将子类的自定义属性superclass指向父类的原型  这样就方便引用到原型实例
//
 r.superclass.constructor.call(this, options) 就可以实现属性冒充.继承父类的构造属性
r.superclass = sp;

// 如果父类不是Object但constructor却指向了Object, 表示父类的原型也被覆盖了 所以要保证正确
//
 这样r.superclass.constructor才能正确指向父类
if (s !== Object && sp.constructor === OP.constructor) {
sp.constructor 
= s;
}

复制代码

 

测试用例:

复制代码
J1616.add(viewfunction(J) {
var SP = Base.prototype;
// 父类构造器
    function Base(name, age) {
this.name = name;
this.age = age;
};
// 父类原型
    J.mix(SP, {
showName: 
function() {
alert(
this.name);
}
});

// 子类继承父类.并实现自己的方法
    function Children(name, age) {
// 对象冒充抄写构造属性
        Children.superclass.constructor.call(this, name, age);
};
// 继承父类
    J.extend(Children, Base);
// 添加showAge方法
    J.augment(Children, {
showAge: 
function() {
alert(
this.age)
}
});
// 实例化子类
    var child = new Children(j161623);
child.showName(); 
// 从父类继承而来 j1616
    child.showAge();  // 后期扩展而来 23
});

复制代码

7.namespace函数

作用: 建立命名空间. 如果该命名空间存在则直接引用.不覆盖.

* S.namespace(‘KISSY.app’); // returns KISSY.app

* S.namespace(‘app.Shop’); // returns KISSY.app.Shop

测试用例:

J1616.namespace(www);
J1616.www.search 
= {
version: 
0.0.1
};
alert(J1616.www.search.version) 
// 0.0.1

 

8.app函数 

作用:建立各个分支模块的app应用.并会对app的_init, add, namespace方法重写.并执行_init

测试用例:

复制代码
J1616.app(J16); // 建立一个J16 App
J16.namespace(www); // 在J16下面建立www命名空间
J16.www.music = {     // J16App的www命名空间下的music模块
    version: 0.0.1
};

alert(J16.www.music.version); // 0.0.1

复制代码

 

剩余两个log函数和error函数没啥可说的.至此kissy.js就结束了.

 

紧接着我们要开始对kissy-lang.js进行分析.

[转载]淘宝Kissy框架分析【二】 - BlueDream - 博客园

mikel阅读(977)

[转载]淘宝Kissy框架分析【二】 – BlueDream – 博客园.

首先,让我们从kissy核心文件夹开始. 第一个文件kissy.js也是主架构文件.

源码如下:

复制代码
/**
* @module j1616
* @author liangchaoyjs@163.com
*/
(
function(win, J, undefined) {
if (win[J] === undefined) win[J] = {};
= win[J];

var doc = win.document,

mix = function(r, s, ov, wl) {
if (!|| !r) return r;
if (ov === undefined) ov = true;
var i, p, l;

if (wl && (l = wl.length)) {
for (i = 0; i < l; i++) {
= wl[i];
if (p in s) {
if (ov || !(p in r)) {
r[p] 
= s[p];
}
}
}
else {
for (p in s) {
if (ov || !(p in r)) {
r[p] 
= s[p];
}
}
}
return r;

},

isReady = false,

readyList = [],

readyBound = false;

mix(J, {
version: @VERSION@,

_init: function() {
this.Env = { mods: {} };
},

add: function(name, fn) {
var self = this;

self.Env.mods[name] = {
name: name,
fn: fn
}

fn(self);
return self;
},

ready: function(fn) {
if (!readyBound) this._bindReady();

if (isReady) {
fn.call(win, 
this);
else {
readyList.push(fn);
}

return this;
},

_bindReady: function() {
var self = this,
doScroll 
= doc.documentElement.doScroll,
eventType 
= doScroll ? onreadystatechange : DOMContentLoaded,
COMPLETE 
= complete;

readyBound = true;

if (doc.readyState === COMPLETE) {
return self._fireReady();
}

//w3c mode
            if (doc.addEventListener) {
function domReady() {
doc.removeEventListener(eventType, domReady, 
false);
self._fireReady();
}
doc.addEventListener(eventType, domReady, 
false);
}
else {
// IE mode
                if (win != win.top) { // iframe
                    function stateChange() {
if (doc.readyState === COMPLETE) {
doc.detachEvent(eventType, stateChange);
self._fireReady();
}
}
doc.attachEvent(eventType, stateChange);
}
else {
function readyScroll() {
try {
doScroll(
left);
self._fireReady();
catch(e) {
setTimeout(readyScroll, 
1);
}
}
readyScroll();
}

win.attachEvent(onloadfunction() {
self._fireReady()
});
}
},

_fireReady: function() {
if (isReady) return;

isReady = true;
if (readyList) {
var fn, i = 0;
while (fn = readyList[i++]) {
fn.call(win, 
this);
}

readyList = null;
}
},

mix: mix,

merge: function() {
var o = {}, i, l = arguments.length;
for (i = 0; i < l; ++i) {
mix(o, arguments[i]);
}
return o;
},

augment: function(r, s, ov, wl) {
mix(r.prototype, s.prototype 
|| s, ov, wl);
return r;
},

extend: function(r, s, px, sx) {
if (!|| !r) return r;

var OP = Object.prototype,
= function(o) {
function F() {}
F.prototype 
= o;
return new F();
},
sp 
= s.prototype,
rp 
= O(sp);

r.prototype = rp;
rp.constructor 
= r;
r.superclass 
= sp;

if (s !== Object && sp.constructor === OP.constructor) {
sp.constructor 
= s;
}

if (px) {
mix(rp, px);
}

if (sx) {
mix(r, sx);
}

return r;
},

namespace: function() {
var l = arguments.length, o = null, i, j, p;

for (i = 0; i < l; ++i) {
= ( + arguments[i]).split(.);
[
appShop]
= this;
for (j = (win[p[0]] === o) ? 1 : 0; j < p.length; ++j) {
= o[p[j]] = o[p[j]] || {};
}
}
return o;
},

app: function(name, sx) {
var O = win[name] || {};

mix(O, thistrue, [_initaddnamespace]);

O._init();

return mix((win[name] = O), typeof sx === function ? sx() : sx);
},

log: function(msg, cat, src) {
if (this.Config.Debug) {
if (src) {
msg 
= src +  + msg;
}
if (win[console!== undefined && console.log) {
console[cat 
&& console[cat] ? cat : log](msg);
}
}
return this;
},

error: function(msg) {
if (this.Config.Debug) {
throw msg;
}
}

});

J._init();

J.Config = { Debug@DEBUG@ };

})(window, J1616);

复制代码

 

首先整个函数通过简单的闭包机制实现了沙箱.然后将win[J]暴露给全局.所以我们就可以J1616.xx引用属性了.

1. mix函数

作用:将s的属性拷贝给r. ov(默认为true)为true则属性覆盖,为false则不覆盖. wl如果定义了.那么只有当s中含有wl定义的属性才会进行属性拷贝.

测试用例:

复制代码
var r = {versionbeta0.0.1};
var s = {
version: 
beta0.0.2,
_init: 
function() {
alert(
init);
},
_login: 
function() {
alert(
login);
},
_logout: 
function() {
alert(
logout);
}
};

var J = J1616;
//////////////////////////////
//
J.mix(r, s);
//
alert(r.version);  // beta0.0.2
//
r._logout();       // logout
//
///////////////////////////
//
J.mix(r, s, false); 
//
alert(r.version);  // beta 0.0.1
//
///////////////////////////
//
J.mix(r, s, true, [‘_init’, ‘_login’]);
//
r._init();   // init
//
r._login();  // login
//
r._logout(); // error
//
///////////////////////////

复制代码

紧接着便用mix(J, {‘_init’:xx}); 实现了将属性赋予J上 其实就 等价于var J = {‘_init’:xxx};

2._init和add函数 

作用:

当j1616.js一加载的时候便会执行_init函数. 这个函数给J维护了一个Env对象. 目前没太大作用.但应该是为了以后扩展接口方便.

add函数. 是注册一个模块. 并将J1616实例传入到回调函数中.

测试用例:

复制代码
(function() {
var J = J1616;
J.add(
module-namefunction(J) {
alert(J.version); 
// 可以获取实例
        J.DOM = {
info: 
function() {
alert(
注册了一个DOM模块);
}
};
});
// 使用定义的module
    J.DOM.info();
})();
复制代码

3. ready函数

作用: 替代onload函数. onload函数需要图片等资源完全加载完毕才调用. 而ready在document构建完毕就开始执行.要更快一些.

原理:

两个标志: (1) isReady记录document是不是已经ready完毕.  (2)readyBound记录是不是已经绑定了ready函数.

一个数组: readyList用来存储排队的需ready执行的函数.

整个流程就是:

如果没有绑定ready 就开始绑定domReady函数. 如果已经绑定并且isReady为true 即文档已经ready完毕.那么就直接执行. 否则就放入readyList列表中存储. 一旦ready完毕 就循环列表,依次执行存储在数组中的函数.

监听domReady的方法:

w3c 使用DOMContentLoaded IE下如果是在iframe中使用onreadystatechange, 非iframe中使用doScroll(‘left’)去检测. 最后使用onload函数兜底.防止onreadystatechange和doScroll晚于onload执行. 由于fireReady中有if (isReady) return;所以保证了函数只会运行一次.

注意: Kissy源码有些问题,在IE下.如果没有图片等资源.页面很快就加载完毕. load函数要早于ready函数…. 所以这里我将ready函数给修正了.

复制代码
_bindReady: function() {
var self = this, DOMContentLoaded = null;
doScroll 
= doc.documentElement.doScroll,
eventType 
= doScroll ? onreadystatechange : DOMContentLoaded,
COMPLETE 
= complete;

readyBound = true;

if (doc.readyState === COMPLETE) {
return self._fireReady();
}

//w3c model
    if (doc.addEventListener) {
DOMContentedLoaded 
= function() {
doc.removeEventListener(eventType, DOMContentedLoaded, 
false);
self._fireReady();
}
doc.addEventListener(eventType, DOMContentedLoaded, 
false);
}
// IE model
    else {
DOMContentedLoaded 
= function() {
if (doc.readyState === COMPLETE) {
doc.detachEvent(eventType, DOMContentedLoaded);
self._fireReady();
}
}
// 主要是这句 onreadystatechange会确保在onload之前执行.而kissy只用在iframe分支里
        // 所以会出现onload要早于domready执行
        doc.attachEvent(eventType, DOMContentedLoaded);
win.attachEvent(
onloadfunction() {
self._fireReady()
});

var toplevel = false;

try {
toplevel 
= win.frameElement == null;
catch(e) {}

if (doScroll && toplevel) {
function readyScroll() {
try {
doScroll(
left);
catch(e) {
setTimeout(readyScroll, 
1);
return;
}
self._fireReady();
}
readyScroll();
}
}
},

_fireReady: function() {
if (isReady) return;

isReady = true;
if (readyList) {
var fn, i = 0;
while (fn = readyList[i++]) {
fn.call(win, 
this);
}

readyList = null;
}
},

复制代码

测试用例:

复制代码
<body>
<img id=inline-image src=http://veimages.gsfc.nasa.gov/2429/globe_west_2048.jpg“/>
<script>
(
function() {
var J = J1616;
J.ready(
function(J) {
alert(
domReady:  + J.version);
});
window.onload 
= function() {
alert(
onload:  + J.version);
}
})();
</script>
</body>
复制代码

4.merge函数 

作用: 将多个对象合并为1个对象.进行的是浅拷贝. 一般用于设置默认参数时候使用:

测试用例:

复制代码
(function() {
J1616.ready(
function(J) {
var source = {
version: 
beta0.0.1,
name: 
kissy
};

var property = {
version: 
beta0.0.2
};

var prototype = {
name: 
j1616
}

var config = J.merge(source, property, prototype);

alert([config.version, config.name]); // version: ‘beta0.0.2’ name: ‘j1616’
    });
})();

复制代码

5.augment函数

作用: 将一个函数的原型和另一个函数的原型或者一个对象合并. 然后也有ov和wl属性, 相当于改进版的mix函数.

测试用例:

复制代码
(function() {
function Base() {};
Base.prototype 
= {
name: 
kissy,
show: 
function() {
alert(
this.name);
}
};

var Base2 = {
name: 
j1616,
};

function Child() {};
Child.prototype 
= {
version: 
beta0.0.1,
show: 
function() {
alert(
this.version);
}
};
// 1.用Base的prototype覆盖Child的prototype. 覆盖的函数列表为show
    // 2.用Base2的属性去覆盖Child的prototype.
    //J1616.augment(Child, Base, true, [‘show’]);
    //J1616.augment(Child, Base2);
    //new Child().show(); // j1616

// 1.将Base的prototype和Child的prototype.属性合并但不覆盖
    // 2.用Base2的属性去覆盖Child的prototype.
    //J1616.augment(Child, Base, false);
    //J1616.augment(Child, Base2);
    //new Child().show(); // beta0.0.1
})();

复制代码

 

[转载]Eclipse 导入项目与 svn 插件关联全过程记录

mikel阅读(1110)

[转载]Eclipse 导入项目与 svn 插件关联全过程记录 – 小鱼儿-lovefishs – 博客园.

今天想整理一下相关项目的前端代码以及目录结构,故利用svn客户端(TortoiseSVN 1.7.2)从trunk上新建了一个branches,然后checkout到本地.
打开Eclipse,点击 File -> Import -> General -> Existing Projects Workspace -> Next -> 选中 select root directory,点击 Browse 浏览,确认项目本地地址,点击 Finish。至此,项目导入完毕。
现在项目已经导入进来了,但是,点击导入的项目右键选择 Team,没有相关的Update以及Commit,出现的是 Share project..等选项。这是因为我们的项目还没有与Eclipse的svn插件相关联。说到这里,我还要补充一点,为什么我在导入项目的时候不选择从 svn上面更新下来呢?我刚开是这么选择的,但是在本地文件中,svn导入下来的项目无法右键update与commit,必须在Eclipse里面选中 相关项目进行svn同步(我对Eclipse不熟,但是我遇到的问题就是这样的,所以我也这么认为,有可能说得不对)
现在我们就来把导入的项目与svn插件相关联,这样一来,我在svn本地文件中也能更新与提交,我在Eclipse里面也能更新与提交。我们在项目上右击,选择Team -> Share Project..然后,杯具的问题出现了,报错了!错误信息“Please upgrade your Subversion client to use this working copy.”提示升级啊,这是个什么情况呢?搜索了一下,找到这么一篇文章:
这里摘取重点部分内容如下:
(1)错误信息:在Eclipse下导入SVN工程后无法关联,右击工程 -> Team -> Share Project… -> SVN 提示如下错误信息
Please downgrading your Subversion client to use this working copy
本地环境:
TortoiseSVN版本:TortoiseSVN 1.5.9
Eclipse下SVN插件版本:Subclipse 1.8.5
解决方案:把Eclipse SVN插件换成 Subclipse 1.6.18即可
(2)错误信息:
Please upgrade your Subversion client to use this working copy.
本地环境:
TortoiseSVN版本:TortoiseSVN 1.7.5
Eclipse下SVN插件版本:Subclipse 1.6.18
解决方案:把Eclipse SVN插件换成 Subclipse 1.8.5即可
Subversion下载地址:

http://subclipse.tigris.org/servlets/ProjectDocumentList?collapseFolder=1730&folderID=2240

这里说了,需要升级,那么好吧,给svn插件升级!我先点击链接下载了Subclise 1.8.x到硬盘,然后怎么升级呢?我不知道啊,再搜索Eclipse安装svn插件,感谢伟大的google。Eclipse安装SVN插件 这篇文章图文并茂的说明了如何在Eclipse中安装svn插件:
3、SVN插件下载地址及更新地址,你根据需要选择你需要的版本。现在最新是1.8.x
Links for 1.8.x Release:
Eclipse update site URL: http://subclipse.tigris.org/update_1.8.x
Links for 1.6.x Release:
Eclipse update site URL: http://subclipse.tigris.org/update_1.6.x
Links for 1.4.x Release:
Eclipse update site URL: http://subclipse.tigris.org/update_1.4.x
4、下载插件包,将插件包复制到Eclipse安装目录。
将插件包features和plugins目录中的文件分别复制到Eclipse安装目录的features和plugins中。然后重启Eclipse 就好了
5、通过Eclipse安装,看图 
 
然后一路点Next,就OK了!!
等等,有什么地方不对?我们的Eclipse是已经装过了svn插件的啊,用这样的方法替换可行吗?(我试过了,是可行的,虽然会报一大堆的错误。。)
好吧,按照正常的思路,我们先卸载svn插件,再安装高版本的,这样应该就没错了。
Eclipse卸载插件比较简单,按图操作就好了:
把svn相关的都卸载(Uninstall)就好了。卸载完成我们重启一下,然后用上面的方法(本地导入,在线安装两者都可)安装新版的svn插件。然后再重启。
重启好以后,重复项目关联svn的动作,Team -> Share Project ,后面就是选择,输入密码之类的,然后就ok了!
总结,这一趟下来,让我对Eclipse了解更深了,以前对这个软件有畏惧,就是因为感觉它配置繁多,我记不住。在查找资料的途中,看到这么一 句话:记不住是因为重复的次数不够多。真心觉得说得太好了。解决问题的过程中不要忽略搜索引擎强大的作用,感谢网络,特把此过程记录分享,希望能够帮助到 有需要的人。

[转载]导出SQL Server中所有Job的最简单方法 - dudu - 博客园

mikel阅读(1045)

[转载]导出SQL Server中所有Job的最简单方法 – dudu – 博客园.

应用场景:

在将源SQL Server数据库服务器中的所有Job(作业)迁移至目标数据库服务器的过程中,需要先将这些Job导出为SQL脚本。

操作步骤:

1、在Microsoft SQL Server Management Studio中,选择SQL Server Agent->Jobs,按F7打开Object Explorer Details窗口,选中所有Job;

2、点击鼠标右键,选择Script Job as->CREATE To->New Query Editor Windows,然后所有Job会以SQL脚本的方式显示在查询窗口中。

 

[转载]微信公众平台消息接口开发(50)在线点歌 - 方倍 - 博客园

mikel阅读(1429)

[转载]微信公众平台消息接口开发(50)在线点歌 – 方倍 – 博客园.

微信 在线听歌 在线点歌 音乐 公众平台 微信公众平台消息接口 微信开发模式 微信公众平台开发模式
作者:http://www.cnblogs.com/txw1958/
原文:http://www.cnblogs.com/txw1958/archive/2013/02/25/weixin-if50-music.html

微信公众平台在年前开放了新的消息接口-音乐消息,这是广大微信公众平台开发者的福音。
根据这一功能,如果能做出在微信中点歌功能,那么我们以后就可以不用安装其他APP,
直接在微信里面关注一个账号,就可以听歌了,还省去了安装的麻烦,而且不用再占用空间。如果音乐资源足够好,那将秒杀一切手机上在线听歌软件也不是没有可能的。
一、获取音乐资源
要做这样一个功能,首先当然是需要有音乐资源,对于普通开发者没有这些资源,怎么办?好在有高人在之前已经找到了相关音乐的API
★搜索QQ音乐
下面这个是QQ音乐的API地址

这个网上搜索不到的,它会返回一个json,注意的是返回的json的key没有用引号引起来而且需要对URL本身和返回的内容使用gb2312编(解)码
然后可以得到这样的不标准json,截取searchCallBack()中间的内容,对key进行加引号,然后就可以用json解码框架来解码

★获取音乐地址

http://stream1歌曲信息中的location值.qqmusic.qq.com/3歌曲ID(7位数,不足在前面补0).mp3

例如之前搜索出来的第一首歌的地址应该是:

第二首歌的地址应该是

这个QQ音乐API还可以获取专辑插图和歌词,但目前还用不上,所以就不讲了。

 

二、封装微信音乐消息
音乐消息格式如下

参数 描述

复制代码
ToUserName 接收方帐号(收到的OpenID) FromUserName 开发者微信号 CreateTime 消息创建时间 MsgType music MusicUrl 音乐链接 HQMusicUrl 高质量音乐链接,WIFI环境优先使用该链接播放音乐 FuncFlag 位0x0001被标志时,星标刚收到的消息。
复制代码

我们对标题,描述,链接进行填写,就能生成一个音乐消息了。
再有微信公众平台账号上的自定义回复设置相关规则,就能实现自动点歌。

 

三、与微信对接

在其中contentStr处改为对接函数就可以了,很简单。

复制代码
//define your token
define("TOKEN", ""); $wechatObj = new wechatCallbackapiTest(); //$wechatObj->valid();
$wechatObj->responseMsg(); class wechatCallbackapiTest { public function valid() { $echoStr = $_GET["echostr"]; //valid signature , option
        if($this->checkSignature()){ echo $echoStr; exit; } } public function responseMsg() { //get post data, May be due to the different environments
        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; //extract post data
        if (!empty($postStr)){ $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $fromUsername = $postObj->FromUserName; $toUsername = $postObj->ToUserName; $keyword = trim($postObj->Content); $time = time(); $textTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Content><![CDATA[%s]]></Content> <FuncFlag>0</FuncFlag> </xml>"; if(!empty( $keyword )) { $msgType = "text"; $contentStr = "Welcome to wechat world!"; $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr); echo $resultStr; }else{ echo "Input something..."; } }else { echo ""; exit; } } private function checkSignature() { $signature = $_GET["signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $token = TOKEN; $tmpArr = array($token, $timestamp, $nonce); sort($tmpArr); $tmpStr = implode( $tmpArr ); $tmpStr = sha1( $tmpStr ); if( $tmpStr == $signature ){ return true; }else{ return false; } } }
复制代码

 

四、效果演示
需要添加 天气神 ,然后发送m,可以看到相关使用说明

1. 发送“点歌”加歌名,如“点歌最炫民族风”,返回指定的歌曲。 2. 只发送“点歌”两个字,系统为您选择一首热门歌曲。 3. 按住说话按钮2秒钟再松开,随机返回一首热门歌曲。

歌曲在WIFI环境中播放很流畅,有很好地体验。

这是点歌成功的界面

这是最上边栏时的显示

这是音乐播放界面

 

原文:http://www.cnblogs.com/txw1958/archive/2013/02/25/weixin-if50-music.html

————————————————————————————————————————–

关注天气神(账号WeatherGod)方法:

1. 依次进入以下路径:朋友们—>添加朋友—>搜号码,输入WeatherGod,不区分大小写,点击查找,然后点击关注

2. 扫描二维码:

猜你喜欢:微信公众平台上的第一个图像处理应用-人脸识别

[原创]SQL获取html中的图片的路径代码

mikel阅读(1754)

项目中需要提出信息内容中的html的图片路径到一个独立的字段,用程序遍历数据量大的表太费时间

于是用SQL直接在数据进行了筛选提出,利用了SQL的substring 和 partindex 函数使用说明见[转载]SQL截取字符串(substring与patindex的使用) – 爱与决择 – 博客园
代码如下:

--更新商品的缩略图
select identifier,substring(productcontent,patindex('%src="%',ProductContent)+5,PATINDEX('%" />%',productContent)-patindex('%src="%',ProductContent)-5) as pp from Tang_Product where ProductContent like '%src=%' and UserId=13022

--去掉alt
update temp_guojingproductpath
set
	pp=substring(pp,0,patindex('%"%',pp))
where
	pp like '%"%'
select
	pp,substring(pp,0,patindex('%"%',pp))
from temp_guojingproductpath

--更新商品的缩略图
update tang_product
set
	ProductImage=pp
from temp_guojingproductpath as p
where
	p.identifier=Tang_Product.Identifier and UserId=13022