【问题标题】:Creating reusable widgets with javascript使用 javascript 创建可重用的小部件
【发布时间】:2014-04-07 13:47:56
【问题描述】:

我正在努力创建小型、可嵌入的小部件,这些小部件在它们自己的 JS 文件之外有一个句柄。

页面结构

例如,我有一个页面,其中可能包含 n 个“power-widget”。 'n' 由为页面提供服务的 Web 服务器确定。 'power-widget' 只不过是一个带有设备名称的 div 及其当前的功耗。当前读数每 5 秒通过 ajax 更新一次。

注意:每个页面都可以有不同的“类型”小部件,尽管下图只有一种类型的小部件。

小部件

每个绿色框是一个在页面加载时初始化的小部件,并以设备名称、颜色等作为参数。每个 type 小部件,在本例中为“power-widget”,都有自己的 JS 和 CSS 文件(以及 HTML 结构),一旦页面检测到这些文件就会异步加载那些是必需的。 因此,可以在我网站的任何页面上呈现相同的小部件。

问题

我编写了代码来检测和加载每个小部件所需的 JS、CSS 和 HTML 内容,并将其放置在所需的 div 中。我编写了一些代码来为小部件创建一个“类类”结构,我可以在其中实例化和编写方法(如更新读数)。

function PowerStatus(options) {
    this.settings = {
        meterName: '',
        mainDiv: null,
        glow: false,
        meterOn: "#91bd09",
        meterOff: "#bc330d",
        meterMid: "#333333"
    };
    this.settings = $.extend(this.settings, options);
    this.settings.mainDiv = $('#' + this.settings.mainDiv);
    this.bindUIActions();
    this.setMeterName();
}

PowerStatus.prototype.setMeterName = function () {
    console.log(this.settings.mainDiv);
    var div = this.settings.mainDiv.find('.load-name');
    var span = $('span:first', div);
    span.text(this.settings.meterName);
};

PowerStatus.prototype.bindUIActions = function () {
    this.settings.mainDiv.on("click", this.divclick);
};

PowerStatus.prototype.divclick = function () {
    console.log(this);
    console.log('Clicked ' + this.settings.meterName);
};

必须在其中放置小部件的页面调用以下代码

var widget = new PowerStatus({meterName: 'Widget 1', mainDiv: 'widget-power-status-1'});

对于所有小部件,从而获得每个小部件的句柄。

在上面的代码中,当我点击 div 时,它会抛出一个

未捕获的类型错误:无法读取未定义的属性“meterName”

因为被传递的被调用者 (this) 实际上是一个 'div' 元素而不是 PowerStatus 对象。有什么线索吗? jQuery 是否传递了它选择的 div? 另外,我想知道这是否是处理整个事情的最干净的方法。我对 JS 很陌生,欢迎任何建议。

【问题讨论】:

    标签: jquery design-patterns widget javascript


    【解决方案1】:

    您需要创建一个对象构造函数,而不是使用对象字面量。

    function PowerStatus( opts ) {
    
      this.init = function( opts ){
    
      }
    
    }
    

    然后:

    var widget = new PowerStatus( opts );
    widget.init();
    

    【讨论】:

    • 一般来说,angular.js 会让这件事变得更容易吗?
    • 我按照您的建议更新了代码 - 看起来不错,但还有另一个问题 - 我已经更新了问题。
    • EmberJS(我的个人偏好)/AngularJS/KnockOut 等将使这些任务变得更容易,但就像任何新技术都需要您学习框架一样。就您的新代码而言,我看不到您在 PowerStatus 对象中设置meterName 的位置?顺便说一句 - StackO 上的最佳实践是创建一个新问题,以便其他人也可以找到您的旧问题并学习。 :)
    • meterName 只是 PowerStatus 类的一个属性。我将使用它来设置小部件的 元素内的文本,以及在查询更新的读数时。知道为什么 JS 的“this”被 jQuery 的“this”所掩盖吗?
    • 抱歉回复晚了,今天比较忙:基本上PowerStatus.prototype.setMeterName应该是this.setMeterName = function()。这将允许您致电this.setMeterName()widget.setMeterName()
    猜你喜欢
    • 2020-01-23
    • 1970-01-01
    • 1970-01-01
    • 2012-06-17
    • 1970-01-01
    • 1970-01-01
    • 2012-02-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多