目录
1 学习方法论
1下定义-针对不同的定义做不同的学习
2如何学习
3 知其所以然的学习
3MVC中页面引擎的入口
4我的定位
(主观的看法很多,说的不好不对的地方请多多指教)
1学习方法
给你要做的事下个定义
我的博士导师跟我说: 如果给问题下准了定义,那么问题就算解决了60%了。
来自《想外行一样思考,想内行一样实践》的一句话。
现在的问题便是你是如何看待razor,准备学习到什么样的程度?
先说说程度问题:
1了解阶段。
看看介绍(如news里面的文章)。知道有这么回事。
2 会用阶段。
那么仅仅是去看一些走马观花式的介绍性文章(比如我那个系列),基本就够你吹吹牛说你会用了。你也可以用在自己的小项目里。这时候你仅需要把所有的公开的API和属性,还有函数名弄懂是怎么回事就OK了。
3掌握应用阶段。
应用阶段不只要知道他是如何使用,更需要知道他的里面的代码是怎么跑的?
1知道里面的架构,知道他是怎么运作的(以便分析性能等)。
2知道他的使用范围和局限性,扩展性等。
我也说的不好,总结得不好,因为我正在这个阶段探索和努力。
4吸收为己用
1 或许是他的实现某个功能的一种机制。如mvvm都有的消息机制。
2 或许是其中的一些较好的写法和做法。比如我从OXITE(link)中学到了使用扩展方法来使得代码优雅,细粒度保持重用性,更好的泛型封装CURD等等。
3 或许是其中一些设计思想。比如一些设计模式,如何对一个大的架构进行解剖和隔离,我在这方面还没上路。
大家互相交流,我也是新手。
2读者类型和我自己的定位
好吧。我的朋友你是如何看待RAZOR的?
类型A:“无所不能”的技术至上的功能派:
如果你只是停留在第一第二阶段,不管你是否自己察觉。但对希望能够进入三,四层感觉,又不知道该如何下手。好吧,交个朋友!希望你能follow我的文章,让我们一起来经历一次这样的体验,真的很棒!
类型B:进阶型:
像我一样是一个脱离了功能派的有点自知之明了。但是又一直在想如何突破天花板,成为小牛。一直徘徊着的家伙们,这里有个同类。我觉得读代码的能力非常重要,对一个框架的深入探究和掌握也是一种非常好的锻炼。so follow me。
类型C:小牛大牛
没什么好说的,欢迎牛牛来指点!
3RAZOR是什么?
如你所知RAZOR是一个“剃须刀”,我这里是指MVC3 自带的页面引擎view engine ,是指这一套类库。
4说了这么多,我们该如何学习呢?
具体的学法参考圣殿骑士的对框架的研究:
1,首先看框架的相关介绍,了解相关的背景、功能、架构图以及其他一些相关信息——认识了解。
2,根据介绍查看并调试框架所提供的实例——熟悉功能。
3,自己写一些相关的项目,主要是熟悉该框架,如果说要急于做项目,后面就可以把框架引入到项目当中——具体使用。
4,根据该框架提供的详细单元测试研究其源码,这也是我最喜欢研究这些开源框架的原因——原理剖析。
5,通过上面的步骤认真分析其原理及细节——准备重现。
6,自己也根据之前的思路重复开发这个框架,最好能用TDD——框架复原捷径。
更多的如何阅读代码,看这里。
5 我自己的总结是这样。
1 是什么。
看介绍性的文章对其有一个基本的了解,知道他是干什么的。看其背景看其产生的原因,往往他产生的原因就是他的最初的核心功能也是最需要学习的。
2 使用它。使用该框架,看官方示例和一些入门系列,和文档来入门。如我们之前的一系列文章。
3了解全貌。有源码就看源码,知道其框架,分几部分,如何实现其核心功能,拆分各部分。心里有数。
4各个击破。拆成各部分后,一个模块一个模块的看。具体可以看接口,看基础类等,看其测试代码了解其要实现的功能。
5吸收。到了这个阶段,从整体到细节一切已经了然于胸,即使一些无聊的派生类等分支也有自信迅速看懂.我也没有什么经验。有的人把别人的框架里面的某些机制变成自己永久代码类库的一部分( 我在积累),有的人以自己重新实现,甚至推出更优的同类的东西。这个看个人了吧。
下载MVC3的源码吧!不过。。。你真的准备好了吗?
http://aspnet.codeplex.com/wikipage?title=MVC&referringTitle=Home
3知其所以然的学习
既然说了这么多废话了,那就多说几句题外话吧。在开始找到MVC3中RAZOR页面引擎的入口前,我想先问一下看官,服务器接收到一个URL请求是如何处理又是在哪里返回给服务器的呢?
昨天看到 invoy给我留言,引起了我的思考。。。越反思,越冒汗。。最近在看的CLR VIA C#(LINK) 也说到了对代码的控制,失控是一件非常恐怖的事,如果你不知道你的代码干了什么,你将随着框架而摇摆,你懂的!
while(time++ && life-- >0 ){
累;
}
die();
这里贴个图
图片来自 HttpApplication处理管道
建议阅读:
Web开发学习心得5——Asp.net的设计思想 这篇写的通俗的,
-----------------------时光荏苒,转眼间你就懂得了一个URL如何传到了HttpApplication-----------------
3MVC中页面引擎的入口
现在让我们进入MVC3中的源码,去解决我们第一个疑惑MVC3中是如何调用RAZOR这个页面引擎的。
STEP1
(参考重典大哥的文章http://www.cnblogs.com/chsword/archive/2010/07/10/1774937.html)
我们找到几个关键的接口。通常从接口开始是个不错的选择。
IView :用于呈现
public interface IView {
void Render(ViewContext viewContext, TextWriter writer);
}
IViewEngine :用于找到页面
public interface IViewEngine {
ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache);
ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache);
void ReleaseView(ControllerContext controllerContext, IView view);
}
利用reflector工具顺藤摸瓜:
添加到类图
这下你应该清楚了
这下类的继承关系就很清楚了。也一目了然RAZOR和WEBFORM viewengine的关系。
STEP2
不去纠缠于细节,跳出来立马思考.我们虽然知道了他们继承于什么,
RAZOR在MVC3中的关系与位置立马清晰了,但是还是不知道到底是在哪里呈现。这时候有两个容易的思路。
第一个:是重典有提到过的一个
ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(new WebPageEngine());
第二个:MVC在Controller 和 view 之间交互的时候。
我是想到了第一个,因为当时由他的文章启发去寻找,结果多费了些功夫。
如果你从第二个思路出发应该会更快。在这个地方我也花费了一点时间。
------时钟滴答-----
我发现了
public abstract class ActionResult {
public abstract void ExecuteResult(ControllerContext context);
}
现在整个思路终于串起来了。
public override void ExecuteResult(ControllerContext context) {
if (context == null) {
throw new ArgumentNullException("context");
}
if (String.IsNullOrEmpty(ViewName)) {
ViewName = context.RouteData.GetRequiredString("action");
}
ViewEngineResult result = null;
if (View == null) {
//1为 content 找到 页面并返回 ViewEngineResult
result = FindView(context);
View = result.View;
}
TextWriter writer = context.HttpContext.Response.Output;
//把所有的需要传递到view的东西都在这里
ViewContext viewContext = new ViewContext(context, View, ViewData, TempData, writer);
//在这里渲染页面
View.Render(viewContext, writer);
if (result != null) {
//发布结果
result.ViewEngine.ReleaseView(context, View);
}
}
1ActionResult 接收ControllerContext 并执行2和3
2IviewEngine负责找到页面
3 IVIEW 对应页面负责render呈现。
在这里就告一段落吧。一般都这里,我都是忍不住喜欢到处逛逛里面是
实现的,和更多的细节。
hi 我的朋友,你是否的朋友是否有所收获?
4我的定位
老赵 说:
希望可以给初学者以合适引导。坚定的北大青鸟反对者,强烈愤慨恶劣的培训机构对于处于懵懂期的初学者以误导,强烈抵制各种虚假广告给业界带来的不良影响,强烈建议有理想有抱负的从业青年放弃北大青鸟,不要做冤大头。
刘伟鹏 说:
知其所以然的学习。
好吧。我还是引用我之前写的一段话,表明我的立场。
一直以来我对自己的定位是处于刚入门而在奋力进阶牛人这个阶段,所以一直希望自己作为一个连接刚入门到高手之间的
一个接力绳,把自己的经验告诉新手,也一直向高手学习。而现在的我,更希望能够得到入门新手的关注,也希望得到牛人们的关注。
让我们用行动把对技术的思考,狂热与掌控传承。。。
作者:撞破南墙
出处:http://www.cnblogs.com/facingwaller/
关于作者:致力ASP.NET MVC/Silverlight/算法/思维/OO/代码之美等。本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
周末没事,就在家里改进了下JCShare这个插件,此次加入了弹窗功能。
先说明下,JCShare的名字纯属是自己的英文名和老婆的英文名第一个字母,并无其他含义:)
弹窗的属性:popupModel 有3个值,分别为:
window:弹窗(window.open)
link:链接方式
showdialog:模态对话框(window.showModalDialog)
-------------------------------------------------------------------------------------------------------------------------------------
简单说点原理:
分享组建目的是把页面的内容,发布到各大网站去,很多网站都提供了此类的接口,像新浪微薄,QQ微薄都有自己的API文档,然后申请一个Appkey,这样可以在发布后,他们能确定来源。
我们只需要利用title, url, content拼接成对应的url,即可把所需的内容发布过去。比如开心网的分享接口地址是:
http://www.kaixin001.com/repaste/share.php
它接收3个参数,rtitle、rurl、rcontent,拼接上去就ok了。
这东西挺简单的,大家随便看看 随便改改吧 哈。
PS:金婚风雨情蛮好看的,适合我们80后,嘿。
昨天分享了 http://jscompress.sinaapp.com/ 这个小工具后,发现大家还是很喜爱的。
因此今天我把它json化了.用json传输数据,也开放了api
本工具所有的功能实现都是由 http://jscompress.sinaapp.com/api 处理.(包括现在可以使用的这个在线压缩)
所有的数据交换均由 HTTP POST 输入处理后由 json 作为数据输出格式.
get={type},{type} 为可选的 compress (压缩) format (格式化) shuffle(混淆)
code=(code),(code) 为必要的源代码. JavaScript的源代码
type={compress},{compress} 注意该参数只有压缩的时候生效,可选 1(默认压缩) 2(YUI压缩) 3(GC压缩)
例:使用 CURL... POST
如果执行成功则返回结果:
{"code":"var a=1,b=2;\n","original_size":"16 Byte","now_size":"13 Byte","status":"Closure Compiler \u538b\u7f29\u5b8c\u6210.","minify":"81.25%"}
然后我写了一个php文件,可以调用这个网站的api,把整个目录所有的js文件压缩或者混淆,格式化后保存到一个新目录。
这样就对那些懒上传文件的同学们基于方便了~~
直接下载地址:
高亮显示
2 /*
3 /## js 合并和压缩PHP脚本...可用于本地或者服务器.
4 /## 本工具只能处理utf-8编码的 *.js 文件.否则会接收不到结果
5 @ 风吟 (fengyin.name)
6 @ http://jscompress.sinaapp.com/
7 */
8 set_time_limit(0);
9 function JsTools($options = array(
10 'basepath' =>'./', //需要处理的脚本路径...
11 'compiled' =>'./compiled/', //处理后新文件的路径...
12 'type' =>'compress', //可选 compress (压缩) format (格式化) shuffle (混淆)
13 'is_merger' =>true, // 是否需要把全部文件合并再进行处理 (压缩,格式化,混淆)
14 'engine' =>'1'//此项只对 type 为 compress 时有效,1(默认) 2 (yui) 3(Closure Compiler)
15 /*
16 yui 和 Google Closure Compiler 压缩是不可逆的,一般情况下使用默认即可
17 不推荐使用混淆.
18 */
19 )){
20 if (is_dir($options['basepath'])) {
21 if ($dh = opendir($options['basepath'])) {
22 while (($file = readdir($dh)) !== false) {
23 if (strpos($file, '.js') !== false && strpos($file, '.min.js') === false) {
24 $js[] = $file;
25 }
26 }
27 closedir($dh);
28 }
29 }
30 if ($options['is_merger']) {
31 foreach($js as $jsfile) {
32 $jscode.= file_get_contents($jsfile).';';
33 }
34 $jscode = json_decode(api($jscode, $options['type'], $options['engine']), true);
35 file_put_contents($options['compiled'].'all.min.js', $jscode['code']);
36 } else {
37 foreach($js as $jsfile) {
38 $jscode = json_decode(api(file_get_contents($jsfile), $options['type'], $options['engine']), true);
39 file_put_contents($options['compiled'].str_replace('.js', '.min.js', $jsfile), $jscode['code']);
40 }
41 }
42 }
43 function api($code, $type, $engine) {
44 $ch = curl_init('http://jscompress.sinaapp.com/api');
45 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
46 curl_setopt($ch, CURLOPT_POST, 1);
47 curl_setopt($ch, CURLOPT_POSTFIELDS, 'get='.$type.'&code='.urlencode($code).'&type='.$engine);
48 $output = curl_exec($ch);
49 curl_close($ch);
50 return $output;
51 }
52 JsTools();
53 ?>