【问题标题】:Shared JavaScript File with Different Definitions of a Function Call具有不同函数调用定义的共享 JavaScript 文件
【发布时间】:2016-08-23 12:39:39
【问题描述】:

我有一个 300 行的 javascript 文件,它为 ASP.NET MVC 应用程序中的多个视图使用的局部视图设置 jQuery 事件处理程序和其他所需的函数。事件处理程序以相同方式处理 99% 的所有内容,无论哪个视图使用部分视图。这个问题大约是 1% 的差异。

由于 JavaScript 没有接口,定义一个函数是否安全,该函数由一个或多个事件处理程序调用,这些事件处理程序处理根据使用的视图加载的单独文件中的不同内容?如果不是,那么处理这种情况的最佳方法是什么?在其他语言中,我会在这种情况下使用接口和/或抽象类。

例子:

共享文件

$(document).ready(function() {
    //shared variables here for methods
    $(document).on('click', '.selectable-table tbody tr', function() {
        //do shared actions
        mySpecificFunction();
        //finish shared actions (if necessary)
    });
});

Definition1.js

function mySpecificFunction() {
   //do stuff
}

Definition2.js

function mySpecificFunction() {
   //do other stuff
}

视图会像这样加载适当的脚本:

<script src="definitionX.js"></script>
<script src="sharedScript.js"></script>

mySpecificFunction() 的“签名”(由于 javascript 而被大量使用)对于每个定义都是相同的,但我的直觉告诉我这是不好的做法。是否有更好/正确的方法或为此目的的设计模式?

【问题讨论】:

  • 如果你想形式化,你考虑过命令模式吗? dofactory.com/javascript/command-design-pattern
  • @YuriyGalanter 我认为这是我需要研究的路线。我承认我不知道很多 JavaScript 的正式设计模式。您还有其他资源吗?或者您可以在答案中发布示例吗?

标签: javascript jquery oop design-patterns


【解决方案1】:

我认为您可以在这里使用 OOP 方法,您不需要抽象类或接口,而是可以使用对象(比其他语言更灵活)。

例如,您可以拥有一个带有共享代码的基本View 原型,然后加载特定的view1.jsview2.js,其中将使用特定代码扩展基本原型:

$(document).ready(function() {
    // view is a view instance coming from the specific view.js
    view.init();
});

// sharedScript.js, view prototype
var View = {
    init: function() {
        $(document).on('click', '.selectable-table tbody tr', function() {
            // do shared actions
            // ...
            // do specific actions
            this.mySpecificFunction();
        });
    },
    mySpecificFunction: function() {
        //do specific things, can be left empty in the "prototype" object
        return;
    }
};

// view1.js
var view = Object.create(View);
view.mySpecificFunction = function() {
    alert('view 1');
}

// view2.js
var view = Object.create(View);
view.mySpecificFunction = function() {
    alert('view 2');
}

并且视图会加载共享的和特定的脚本:

<script src="sharedScript.js"></script>
<script src="view1.js"></script>

这只是一个粗略的想法,可以改进,例如,您可能希望将所有 js 代码连接并压缩到单个文件中以用于生产。在这种情况下,来自view1.jsview2.js 等的全局view 变量将成为问题。

改进可以是某种“路由器”,它将检测应该实例化的视图:

$(document).ready(function() {
    router.when('/', function() {
       view = HomePageView();
    }).when('/about', function() {
       view = AboutPageView();
    });
    view.init();
});

【讨论】:

  • 这正是我正在寻找的类型。谢谢你解释得这么清楚。我当然需要开始学习更多的 JavaScript 设计模式,因为我不再总是做后端工作了!
  • @JNYRanger 我还建议研究一些现代框架(角度或反应)。我从大部分工作在后端完成的 Web 应用程序转移到使用 jQuery 的更繁重的客户端应用程序,并从那里转移到客户端的 Angular 应用程序,这确实令人印象深刻。基本上它允许在客户端轻松构建整个 UI,而您的后端只能提供 json 格式的数据。
【解决方案2】:

上述方法可行,但就可维护性而言,它不是最好的方法。通过脚本标签添加一个或另一个文件以导入特定功能 不一定要让其他开发人员清楚您实际上已经更改了共享代码中事件处理程序的行为。

一个简单的替代方法是,在每个视图中,您可以将部分视图包装在一个包含元素中,该元素具有一个标识 css 类,以区分该点所需的行为。

然后为这些不同的 css 类分别分配事件处理程序:

$(document).ready(function() {
    //shared variables here for methods     

    $(document).on('click', 'div.type1 .selectable-table tbody tr', function() {
        //do shared actions
        mySharedActions();
        mySpecificFunction1();
        //finish shared actions (if necessary)
    });

    $(document).on('click', 'div.type2 .selectable-table tbody tr', function() {
        //do shared actions
        mySharedActions()
        mySpecificFunction2();
        //finish shared actions (if necessary)
    });
});

这将允许您将所有特定功能放在一个地方,并使 css 类所预测的变化行为显式 供未来的开发者查看。

【讨论】:

    猜你喜欢
    • 2023-03-20
    • 2015-08-18
    • 1970-01-01
    • 2011-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-21
    相关资源
    最近更新 更多