Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript代码组织数据驱动应用程序_Javascript_Jquery_Asp.net Mvc_Design Patterns_Kendo Ui - Fatal编程技术网

Javascript代码组织数据驱动应用程序

Javascript代码组织数据驱动应用程序,javascript,jquery,asp.net-mvc,design-patterns,kendo-ui,Javascript,Jquery,Asp.net Mvc,Design Patterns,Kendo Ui,我目前正在从事一个中型/大型数据驱动的Asp.net MVC应用程序的前端工作,我对遵循正确的代码组织/设计模式有一些疑问。 web应用程序由多个页面组成,其中包含许多使用Razor模板定义的Kendo UI MVC小部件 对于那些不熟悉剑道的人,razor语法被翻译成Javascript,如下代码片段: 我在我的脚本文件夹中定义了两个主文件夹,我的js文件结构如下: shared//包含共享的js文件 -file1.js -file2.js 页面//每页一个文件 第1.js页 第2.js

我目前正在从事一个中型/大型数据驱动的Asp.net MVC应用程序的前端工作,我对遵循正确的代码组织/设计模式有一些疑问。 web应用程序由多个页面组成,其中包含许多使用Razor模板定义的Kendo UI MVC小部件

对于那些不熟悉剑道的人,razor语法被翻译成Javascript,如下代码片段:

我在我的脚本文件夹中定义了两个主文件夹,我的js文件结构如下:

  • shared//包含共享的js文件 -file1.js -file2.js

  • 页面//每页一个文件

    • 第1.js页
    • 第2.js页
    • Ticket.js//第4页:)
每个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/JAVASCRIPT 我觉得我的设计模式可能对其他前端delevoper不友好,主要是因为我选择不在Jquery插件中实现Javascript模块

首先,我做每件事都错了吗?
其次,我的设计模式适合Javascript测试框架吗?
第三个,Jquery插件必须具备哪些场景

更新 通过上述Razor语法添加了Javascript输出


您可以尝试将文件分为不同的组件,因为每个组件都有一个文件夹

例如:第1页是关于矩形的,因此您在该文件夹中创建了3个文件,分别是rectangle.component.html、rectangle.component.css、rectangle.component.js(可选的用于测试的rectangle.spec.js),并调用了rectangle

所以,如果有什么不好的事情发生在一个矩形上,你就知道问题出在哪里了

隔离变量并在正确位置执行的一个好方法是使用一个路由器,它在url上检查并执行您登录到该页面的代码部分


如果您需要更多帮助,请告诉我

组织和模式似乎不错,但我有一些建议:

提示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或其他名称,而无需实际更改模块的内部代码

提示2: 忘记技巧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);
您只需要担心一个全局变量。

文件夹结构 就功能(共享)和模块(模块化方法)而言,开发或应用程序代码应该代表您在HTML中可能遇到的内容。对解决方案执行简单的ctrl+f组合键应该会产生所有可能的更改。根据多年来的经验,我个人更喜欢将其分为:

  • 应用程序(应用程序代码)
    • 类(可重用)
    • 模块(单体)
  • lib(包管理器/grunt/gulp/…)
    • jquery(正确的库名称/未统一的dist文件或根文件)
    • 剑道
文件名 表示某物的功能并能够在一眨眼之间重用它,这将缩短您的开发时间。我相信你也知道,选择专有名称是有价值的。我的文件名总是以
名称空间
开头,通常简短地说,后跟一个可重用的“搜索”术语:

  • 应用程序/原型
    • ns.calendar.js(多个配置)
    • ns.maps.js(组合或单独使用)
    • ns.places.js(表单或地图加载项)
    • ns.validation.js(多表单和一般处理)
  • 应用程序/单身人士
    • ns.cookiebox.js(单一配置)
    • ns.socialmedia.js(单一配置)
    • ns.dom.js(提供dom更正、全局调整大小事件、小部件等的位置)
要补充的是,你们所谓的共享,是指全球性的功能。一个很好的例子是使用下划线库。或者自己创建一个函数集合(设备检测、节流、帮助器),以便在整个项目中重用=>ns.fn.js 由于在整个名称空间中只添加一次,因此它也构建为单例,可以添加到modules文件夹或直接添加到app root中

最后添加一个加载程序文件,以启动应用程序根目录中的控制点=>ns.load.js。该文件保存单个DOM就绪事件以绑定原型和模块

因此,您可能需要重新考虑将页面划分的想法。相信我,我去过那里。在某个时候,您会注意到,为了单独配置所有页面并重复配置,功能变得太大

文件结构 老实说,我最喜欢@TxRegex answer的技巧1,它添加了一个小的选项来绑定名称空间,并在加载名称空间时将其从一个文件传递到另一个文件

核心原则:生命绑定到窗口对象 有关更多示例代码,我想
;(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);
window.NameSpace = (function($, ns){
    'strict'
    function private(){}
    var x;
    ns.SearchTerm = {};
    return ns;
}(window.jQuery, window.NameSpace || {}));