如果requireJS模块在$上设置全局,如何仅在分配全局时执行模块代码?

时间:2013-04-26 14:07:45

标签: javascript jquery module requirejs jqplot

我正在尝试加载jqplot作为requireJS模块。

我的main.js有一条路径和垫片:

require.config({
  , paths: {
      plot:          '../js/plugins/jqplot/jqplot.module'
  } 
  , shim: {
    'plot':          { deps: ['jquery']}
  }
});

由于大多数网页都不需要此模块,我正在等待 pageXYZ 加载,然后在<script></script>内,我正在呼叫:

require(['plot'], 
    function (plot) {
       // do stuff
    }
);

我的jqplot.module看起来像这样:

define(['../js/plugins/jqplot/jquery.jqplot'],
    function () {
        require([
                '../js/plugins/jqplot/plugins/jqplot.barRenderer'
              , '../js/plugins/jqplot/plugins/jqplot.logAxisRenderer'
              , '../js/plugins/jqplot/plugins/jqplot.categoryAxisRenderer'
              , '../js/plugins/jqplot/plugins/jqplot.canvasAxisTickRenderer'
              , '../js/plugins/jqplot/plugins/jqplot.canvasTextRenderer'
              , '../js/plugins/jqplot/plugins/jqplot.pointLabels'
              , '../js/plugins/jqplot/plugins/jqplot.enhancedLegendRenderer'
        ], 
        function (){
          return $.jqplot;
        }
    );
  }
);

返回正确的对象,并定义和使用所有子插件。

但是,我的做东西代码之前 jqplot已分配给$,所以我的代码仍然会出现未定义的错误运行(我假设,因为文件都已加载,所以requirejs开始运行)

问题
在将jqplot分配给$?

之前,我该怎么做才能暂停代码执行

2 个答案:

答案 0 :(得分:3)

1)我认为这一行来自你的问题:

define(['../js/plugins/jqplot/jquery.jqplot'],

应为:

define(['../js/plugins/jqplot/jquery.module'],

2)您不需要shim,因为您有一个加载jqplot的模块定义。因此,请将requirejs.config更改为

require.config({
  , paths: {
      plot:          '../js/plugins/jqplot/jqplot.module'
  } 
});

3)你的jqplot.module现在没有返回任何内容。将其更改为:

define([
      '../js/plugins/jqplot/jquery.jqplot'
    ],
    function () {
        var plot;
        require([
            '../js/plugins/jqplot/plugins/jqplot.barRenderer',
            '../js/plugins/jqplot/plugins/jqplot.logAxisRenderer',
            '../js/plugins/jqplot/plugins/jqplot.categoryAxisRenderer',
            '../js/plugins/jqplot/plugins/jqplot.canvasAxisTickRenderer',
            '../js/plugins/jqplot/plugins/jqplot.canvasTextRenderer',
            '../js/plugins/jqplot/plugins/jqplot.pointLabels',
            '../js/plugins/jqplot/plugins/jqplot.enhancedLegendRenderer'
            ],
        function () {
            plot = $.jqplot;
        });
        return plot;
    });

这都是未经测试的,但我认为这些应该有所帮助

答案 1 :(得分:1)

回答这个问题和所有重复,上面的基本答案是关闭但没有雪茄,因为要求是异步的,因此需要可以/将在定义闭包关闭并返回之前触发,下面的异步安全解决方案:

讨厌的问题,因为它是三个依赖的链

jqplot插件需要jqplot需要jquery,我有一个基于与上面相同的简单解决方案

首先执行你的requirejs“main.js”配置

requirejs.config({
    paths: {
        "jquery": "path/to/jquery-1.10.2.min",

        // WORKAROUND : jQuery plugins + shims
        "jqplot.core": "path/to/jquery-jqplot-1.0.8.min",
        "jqplot": "jquery-jqplot-module-with-plugins-1.0.8"
    },
    shim: {
        "jqplot.core": {deps: ["jquery"]},
        "jqplot": {deps: ["jqplot.core"]}
    }
});

创建一个名为“jquery-jqplot-module-with-plugins-1.0.8.js”的包装器文件模块文件,其中包含:

// wraps jquery jqplot plugin in define statement
define([
    "jquery",
    "path/to/jqplot.highlighter.min",
    "path/to/jqplot.cursor.min",
    "path/to/jqplot.dateAxisRenderer.min",
    "path/to/jqplot.canvasTextRenderer.min",
    "path/to/jqplot.canvasAxisLabelRenderer.min",
    "path/to/jqplot.enhancedLegendRenderer.min",
    "path/to/jqplot.pieRenderer.min",
    "path/to/jqplot.donutRenderer.min",
], function($) {
    var jqplot;
    jqplot = $.jqplot;
    return jqplot;
});

然后当你需要jqplot与这些插件时,只需调用“jqplot”,它将加载“jquery”然后“jqplot.core”然后所有的jqplot模块,然后最后返回jqplot对象:)

require(["jquery", "jqplot"], function ($, $jqplot) {
    console.log("Success..Inside Require JS");
    console.log("Plot...", $.jqplot, $jqplot);
});

define(["jquery", "jqplot"], function ($, $jqplot) {
    console.log("Success..Inside Define JS");
    console.log("Plot...", $.jqplot, $jqplot);
});

多田! :)

ps jquery插件是邪恶的,没有建议如何解决这种情况,只是一个事实陈述

欢呼声

蚂蚁