我目前正在开发中型/大型数据驱动的 Asp.net MVC应用程序的前端,我对正确的代码组织/设计有些怀疑模式要遵循。 Web应用程序由多个页面组成,其中包含使用Razor模板定义的许多Kendo UI MVC小部件。
对于那些不熟悉Kendo的人,剃刀语法被转换为Javascript,如下面的代码片段所示: the other
我在我的脚本文件夹中定义了两个主要文件夹,我按照以下方式构建了我的js文件:
shared //包含共享的js文件 -file1.js -file2.js
页面//每页一个文件
每个js文件都是使用以下模式定义的单独模块:
注意:内部meet
函数会将每个回调函数注册到窗口事件,有时会注册init
块。
$(document).ready(function(){})
一旦我需要在模块中定义的Javascript函数,我在页面中包含相关的Javascript文件。 我的对象的一个istance存储在一个变量中,最重要的是,一个函数绑定到widget事件(参见:onRequestStart)。
;(function () {
"use strict";
function Ticket(settings) {
this.currentPageUrls = settings.currentPageUrls;
this.currentPageMessages = settings.currentPageMessages;
this.currentPageEnums = settings.currentPageEnums;
this.currentPageParameters = settings.currentPageParameters;
this.gridManager = new window.gridManager(); //usage of shared modules
this.init();
}
Ticket.prototype.init = function () {
$("form").on("submit", function () {
$(".window-content-sandbox").addClass("k-loading");
});
...
}
Ticket.prototype.onRequestStart = function (e) {
...
}
//private functions definition
function private(a, b, c){
}
window.Ticket = Ticket;
}());
我觉得我的设计模式可能和其他前端delevoper一样不友好,主要是因为我选择不在Jquery插件中实现Javascript模块。
首先,我做错了吗? 第二,我的设计模式是否适合Javascript测试框架? 第三,这是Jquery插件的必备方案吗?
通过上述Razor语法添加了Javascript输出。
答案 0 :(得分:5)
在功能(共享)和模块(模块化方法)方面,开发或应用程序代码应代表您在HTML中可以遇到的内容。对解决方案进行简单的ctrl + f应该会产生所有可能的更改。根据多年来的经验,我个人更喜欢将其划分为:
代表什么做了什么,并且能够在眨眼之间重复使用它将会缩短你的开发时间。选择合适的名字具有价值,因为我确信你知道。我的文件名通常以namespace
开头,通常是短暂的,然后是可重复使用的"搜索"术语:
要添加,您所谓的共享,是指全球化的功能。一个很好的例子是使用下划线库。或者自己创建一系列功能(设备检测,油门,帮助器),以便在整个项目中重复使用=> ns.fn.js 由于您只在整个命名空间中添加它们一次,因此它也可以构建为单例,可以添加到模块文件夹中或直接添加到应用程序根目录中。
最后添加一个启动你的控制点的加载文件=>应用程序根目录中的ns.load.js。该文件包含单个DOM ready事件以绑定原型和模块。
所以你可能想重新考虑分成页面的想法。相信我,我一直在那里。在某些时候,您会注意到功能如何变得太大,以便分别配置所有页面,反复配置。
老实说,我喜欢@TxRegex的提示1回答最多,只需添加一小部分来绑定命名空间,并在文件加载时将其从文件传递给文件。
window.NameSpace = (function($, ns){
'strict'
function private(){}
var x;
ns.SearchTerm = {};
return ns;
}(window.jQuery, window.NameSpace || {}));
有关更多示例代码,我想指出我的github account。
尝试从lib到app实现单个捆绑和缩小的文件,加载到head
async
上用于生产版本。在defer
上使用分离和未分解的脚本文件进行开发和调试。如果执行此操作,则必须避免整个项目中具有全局依赖性的内联脚本。
输出=> ns.bundle.js => ns.bundle.min.js
通过这种方式,您可以避免JavaScript中的渲染阻塞问题并加快加载过程,从而加快搜索引擎优化。此外,您还可以动态组合移动布局和桌面布局的功能,而不会出现内存问题或不稳定的行为。从加载器文件调用实例时,实际上很好地缩小并产生很少的开销。由于单个包将在整个页面中缓存,因此所有这些都取决于您可以从包中删除多少依赖项或库。理想情况下适用于可以共享代码并插入不同项目的中型和大型项目。
another post中的更多信息。
首先,我做错了吗?
其次,我的设计模式是否适合Javascript测试框架?
jQuery is undefined
</body>
捆绑解决方案。第三,哪些是Jquery插件的必备方案?
写一次,在必要时轻松适应并配置充足!
答案 1 :(得分:1)
组织和模式似乎很好,但我有一些提示:
您可以返回对象,而不是在模块中设置特定的全局变量。所以不要这样做:
;(function () {
"use strict";
function Ticket(settings) {
console.log("ticket created", settings);
}
...
window.Ticket = Ticket;
}());
你会这样做:
;window.Ticket = (function () {
"use strict";
function Ticket(settings) {
console.log("ticket created", settings);
}
...
return Ticket;
}());
这样做的原因是能够获取模块代码并在需要时为其提供不同的全局变量名称。如果存在名称冲突,您可以将其重命名为MyTicket或其他任何内容,而无需实际更改模块的内部代码。
忘记提示1,全局变量发臭。为什么不创建对象管理器并使用单个全局变量来管理所有对象,而不是为每个对象类型创建单独的全局变量:
window.myCompany = (function () {
function ObjectManager(modules) {
this.modules = modules || {};
}
ObjectManager.prototype.getInstance = function(type, settings) {
if (!type || !this.modules.hasOwnProperty(type)) {
throw "Unrecognized object type:";
}
return new this.modules[type](settings);
};
ObjectManager.prototype.addObjectType = function(type, object) {
if (!type) {
throw "Type is required";
}
if(!object) {
throw "Object is required";
}
this.modules[type] = object;
};
return new ObjectManager();
}());
现在,您可以使用附加了公司名称的单个全局对象管理每个模块。
;(function () {
"use strict";
function Ticket(settings) {
console.log("ticket created", settings);
}
...
window.myCompany.addObjectType("Ticket", Ticket);
}());
现在,您可以轻松地为每个对象类型获取一个实例,如下所示:
var settings = {test: true};
var ticket = window.myCompany.getInstance("Ticket", settings);
你只需担心一个全局变量。
答案 2 :(得分:-1)
您可以尝试在不同的组件中分隔文件,因为每个组件都有一个文件夹。
例如:第1页是关于矩形的,所以你在该文件夹中创建一个文件夹调用矩形,你创建了3个文件rectangle.component.html,rectangle.component.css,rectangle.component.js(可选的rectangle.spec.js for测试)。
app
└───rectangle
rectangle.component.css
rectangle.component.html
rectangle.component.js
所以,如果有任何不好的事情发生在矩形上,你知道问题在哪里
隔离变量并在正确的位置执行的一种好方法是使用路由器基本上它在URL处检查并执行您指向该页面的代码部分
希望如果您需要更多帮助,请告知我们。