我正在尝试在canjs中创建应用程序的MVC结构。为此,我使用requireJS来分隔不同文件中的代码。
我在谷歌搜索过,我正在关注这个tutorial,但在那个tutorail我找不到访问不同模块中的模块变量。因此我遵循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
}
});
正在加载每个文件(在网络tab-chrome devtools中看到)但输出中没有填充任何内容。
任何人都可以帮助我吗? 提前谢谢!
答案 0 :(得分:2)
继续使用@ekuusela所说的内容,以这种格式重构Player.js
中的代码:
define(['PlayerModel'],function(){
function PlayerModel(){ ... }
return {
PlayerModel: PlayerModel
}
});
在内部,定义模块时遵循两个约定。这些涉及:
将文件名作为模块的名称(除非使用shim
,否则就像你一样)。换句话说,define(['Module_Name'] ...)
,这就是我通常读取该行的方式,可以更准确地读作define(['Module_Path_Or_Shim_Symbol_Name' ...)
模块并不神奇 - 它只是一个特殊标记的函数映射。此映射由RequireJS维护,可能与此类似:
var ModuleMap = {
'Player' : function (...) { ... },
'PlayerModel' : function (...) { ... }
};
每次访问模块时,通过require
或define
调用,都会访问此地图,并找到相关的功能。但是,这还不够 - 我们想要的是在函数中定义的东西 - 模块的基本概念是它们内部的所有东西都有模块功能范围,并且不暴露在外面。因此,为了获得对这些"东西"的访问权限,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 (...) { ... }
};
这意味着用模块函数编写的代码最多只能执行一次。
答案 1 :(得分:1)
您在PlayerModel
中定义函数player.js
,然后需要一个名为PlayerModel
的模块,但不要将所需模块分配给任何变量。您应该首先清理代码,可能重命名一些模块并移动函数。
在这里,您尝试访问模块PlayerModel
中的函数player
,但player.js
中的模块工厂函数不返回任何内容:
require(["player"],function(player){
player.PlayerModel();
});
为函数参数player
分配的内容只是从定义模块的函数返回的内容。 (如果要将模块定义为对象,则该对象将成为参数。)