使用 requirejs 从不同的文件(模块)访问变量

Accessing variable from different files(module) using requirejs

我正在尝试在 canjs 中制作应用程序的 MVC 结构。为此,我使用 requireJS 来分隔不同文件中的代码。

我在 google 中进行了搜索,我正在按照此 tutorial but in that tutorail I dont find to access module variables in different modules. therefore I am following this 方法进行搜索。

但我做不到。 这是我的代码:

requirejsconfig.js 文件:

  requirejs.config({
   paths :{
    enforceDefine: true,
    waitSeconds : 0,
    jquery      : "https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min", 
    main        : "view/main",
    player      : "view/player",
    PlayerModel : "/models/PlayerModel",
    hbs         : "/models/view/js/handlebars",
    fixture     : "/models/view/js/can.fixture", 
    can         : "/models/view/js/can.jquery"

 }
});

main.js :

require(["player"],function(player){
    player.PlayerModel();
 });

我想在我的控制器中使用该模型方法。

player.js :

 define(['PlayerModel'],function(){

     function PlayerModel(){   
        var Player = PlayerModel.Player;
         Players =can.Control({ defaults :{view:view/players.hbs' }},{
            init: function(){
                this.element.html(can.view(this.options.view, {
                    players: this.options.players
                }));
            }
      $(document).ready(function(){
        $.when(Player.findAll()).then(
         function(playersResponse){
            var players = playersResponse[0];      

            new Players('.players', {
                players: players
             });
         });
    });
  }
});

PlayerModel.js:

   define(function(){

        var Player = can.Model({
            findAll: 'GET /models/players.json',
            findOne: 'GET /players.json/{id}'
        });
        return {
            Player:Player
        }
    });

正在加载每个文件(在网络选项卡-chrome devtools 中看到)但没有在输出中填充任何内容。

有人可以帮助我吗? 提前致谢!

您在 player.js 中定义函数 PlayerModel,然后在那里需要一个名为 PlayerModel 的模块,但不要将所需的模块分配给任何变量。你应该首先清理你的代码,可能重命名你的一些模块并移动函数。

在这里,您尝试访问模块 player 中的函数 PlayerModel,但是 player.js 中的模块工厂函数没有 return 任何东西:

require(["player"],function(player){
   player.PlayerModel();
});

分配给函数参数 player 的只是您从定义模块的函数中 return 得到的任何东西。 (如果您将模块定义为对象,那么该对象就是参数。)

继续@ekuusela 所说的,将 Player.js 中的代码重构为以下格式:

define(['PlayerModel'],function(){
  function PlayerModel(){ ... }
  return {
    PlayerModel: PlayerModel
  }
});

发生了什么事

在内部,定义模块时遵循两个约定。这些涉及:

  1. 模块叫什么(它的标签)
  2. 这个标签代表什么。

标记模块

文件名被用作模块的名称(除非像您一样使用 shim)。换句话说,define(['Module_Name'] ...),这是我通常阅读该行的方式,可以更准确地读作 define(['Module_Path_Or_Shim_Symbol_Name' ...)

这是什么'Module'总之

模块并不神奇——它只是一个特殊标记的函数映射。此地图由 RequireJS 维护,可能看起来类似于:

var ModuleMap = {
  'Player' : function (...) { ... },
  'PlayerModel' : function (...) { ... }
};

每次访问模块时,通过requiredefine 调用,都会访问此映射,并找到相关函数。然而,这还不够 - 我们想要的是在函数 中定义的东西 - 模块的基本概念是它们内部的所有内容都具有模块功能范围,并且不会暴露外部。因此,为了访问这个 "stuff",RequireJS 大脑做了它 可以 对函数做的唯一事情——执行它。

var playerReference = require('Player');

请注意,我使用了要求模块的 CommonJS 表示法,这对于我们当前的目的而言更具可读性。

因此,在您发布的代码中,模块函数 定义并声明了 PlayerModel 作为函数,但没有 公开它 .由于行 player.PlayerModel() 期望模块 return 一个对象 属性 名为 PlayerModel 引用你的函数,所以模块的逻辑 return 值是:

var exposedModuleReference = { PlayerModel: PlayerModel };
return exposedModuleReference;

请注意,这意味着公开函数的名称可以与函数名称本身不同。例如,下面的代码将 工作而无需在其他任何地方进行任何更改:

define(['PlayerModel'],function(){
  function PlayerModelConstructor(){ ... }
  return {
    PlayerModel: PlayerModelConstructor
  }
});

一个有趣的补充

因此,执行模块函数并将该 return 值分配给引用是 RequireJS 大脑所做工作的一部分。另一部分是,它然后更新这张地图,现在它看起来像这样:

var ModuleMap = {
  'Player' : { PlayerModel: PlayerModelConstructor },
  'PlayerModel' : function (...) { ... }
};

这意味着在模块函数中编写的代码最多执行一次。