我目前正在研究中/大规模数据驱动的 Asp.net MVC应用程序的前端,我对遵循正确的代码组织/设计模式有些怀疑。Web应用程序由多个页面构成,其中包含许多使用Razor模板定义的Kendo UI MVC小部件。
对于那些不熟悉剑道的人来说,剃刀的语法会被翻译成Javascript,如下所示:
我在我的脚本文件夹中定义了两个主文件夹,并按照以下方式构建了我的js文件:
每个js文件都是用以下模式定义的单独模块:
注意:内部init
函数将每个回调函数注册到窗口事件并偶尔会注册一个$(document).ready(function(){})
块。
;(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;
}());
一旦我需要我在模块中定义的Javascript函数,我会在页面中包含关联的Javascript文件。我的对象的存储被存储在一个变量中,最重要的是,一个函数被绑定到小部件事件(参见:onRequestStart)。
@(Html.Kendo().DropDownList()
.Name("Users")
.DataValueField("Id")
.DataTextField("Username")
.DataSource(d => d.Read(r => r.Action("UsersAsJson", "User"))
.Events(e => e.RequestStart("onRequestStart"))))
var settings = {};
var ticket = new window.Ticket(settings);
function onRequestStart(e){
ticket.onRequestStart(e);
}
我觉得我的设计模式可能对我的其他前端删除器不友好,主要是因为我选择不在Jquery插件中实现Javascript模块。
首先,我做错了什么? 其次,我的设计模式适合Javascript测试框架吗? 第三,哪些是Jquery插件的必备场景?
发布于 2018-03-22 16:12:01
在功能(共享)和模块(模块化方法)方面,开发或应用程序代码应代表您可以在HTML中遇到的内容。您的解决方案上的一个简单的ctrl + f应该会产生所有可能的更改。根据多年来的经验,我个人更喜欢将其分为:
代表什么事情,并能够在瞬间重用它,会减少你的开发时间。选择正确的名字是有价值的,因为我相信你知道。我的文件名通常始于namespace
简而言之,随后是可重复使用的“搜索”术语:
补充一下,你称之为共享的功能是全球性的。一个很好的例子是使用下划线库。或者自己创建一个函数集合(通常是设备检测,扼制器,帮助器),以便在整个项目中重用=> ns.fn.js由于您只在整个名称空间中添加它们一次,因此它也构建为单例,并且可以添加到模块文件夹或直接在应用程序根目录中。
作为最后一个加载文件来启动你的控制点=> ns.load.js在应用程序根目录中。该文件包含单个DOM就绪事件来绑定原型和模块。
所以你可能想重新考虑你分页的想法。相信我,我一直在那里。在某些时候,您会注意到功能增长过大以便为所有页面单独配置和重复配置。
说实话,我喜欢@TxRegex的Tip 1回答最多,除了绑定命名空间并在文件加载时将其从文件传递到文件时,我们还有一点小小的补充。
window.NameSpace = (function($, ns){
'strict'
function private(){}
var x;
ns.SearchTerm = {};
return ns;
}(window.jQuery, window.NameSpace || {}));
有关更多示例代码,我想指出我的github帐户。
努力实现从LIB单一的捆绑和精缩文件的应用程序,在装head
上async
的产品发布。defer
为了开发和调试目的,使用分离和未分级的脚本文件。如果你这样做,你必须在整个项目中避免使用全局依赖的内联脚本。
输出=> ns.bundle.js => ns.bundle.min.js
这样你就可以避免JavaScript中的渲染阻塞问题,并加速加载过程,从而提高搜索引擎优化。此外,您还可以即时将移动设备布局和桌面布局的功能组合起来,而不会出现内存问题或不稳定行为。很好地完成缩减,并且在从加载程序文件调用实例时产生很小的开销。由于单个软件包将缓存在整个页面中,这取决于您可以从软件包中删除多少依赖项或库。理想情况下适用于代码可以共享并插入不同项目的大中型项目。
更多信息在另一篇文章中。
首先,我做错了什么?
其次,我的设计模式适合Javascript测试框架吗?
jQuery is undefined
</body>
捆绑解决方案。第三,哪些是Jquery插件的必备场景?
写一次,在需要的地方轻松调整,并配置很多!
发布于 2018-03-22 16:46:15
组织和模式似乎很好,但我有一些提示:
您可以不用在模块中设置特定的全局变量,而是可以返回对象。所以不要这样做:
;(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);
而你只有一个全局变量需要担心。
https://stackoverflow.com/questions/-100004295
复制相似问题