【问题标题】:Accessing variable from different files(module) using requirejs使用 requirejs 从不同的文件(模块)访问变量
【发布时间】:2015-06-22 11:31:42
【问题描述】:

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

我在谷歌搜索过,我正在关注这个tutorial,但在那个教程中我找不到访问不同模块中的模块变量。因此我遵循this 方法这样做。

但我无法做到这一点。 这是我的代码:

需要jsconfig.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
        }
    });

正在加载每个文件(在 network tab-chrome devtools 中看到),但输出中没有填充任何内容。

谁能帮帮我? 提前致谢!

【问题讨论】:

  • 看起来在 PlayerModel() 内部,您正在访问 PlayerModel.Player。看起来你没有在任何地方定义过。
  • 我已经定义好了。更新了我上面的代码。

标签: javascript requirejs canjs


【解决方案1】:

继续@ekusela 所说的,以这种格式重构Player.js 中的代码:

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

发生了什么

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

  1. 模块的名称(其标签)
  2. 这个标签代表什么。

标签模块

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

这个“模块”到底是什么

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

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

每次访问模块时,通过requiredefine 调用,访问此映射,并找到相关函数。然而,这还不够——我们想要的是定义在函数中的东西——模块的基本概念是它们内部的所有东西都有模块函数作用域,而不是暴露在外面。因此,为了访问这些“东西”,RequireJS 大脑只做了它可以对一个函数做的事情——执行它。

var playerReference = require('Player');

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

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

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

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

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

一个有趣的补充

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

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

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

【讨论】:

  • 感谢您明确我对模块的概念。这是非常明确和有用的答案。我很感激这个答案!再次感谢。!
【解决方案2】:

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

这里,你尝试访问模块player中的函数PlayerModel,但是player.js中的模块工厂函数没有返回任何内容:

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

分配给函数参数player 的只是您从定义模块的函数返回的任何内容。 (如果您将模块定义为对象,那么该对象就是参数。)

【讨论】:

  • 谢谢你的答案!!
猜你喜欢
  • 2012-09-09
  • 1970-01-01
  • 2019-10-28
  • 1970-01-01
  • 2011-12-19
  • 1970-01-01
  • 2016-04-28
  • 2023-02-04
  • 1970-01-01
相关资源
最近更新 更多