javascript - RequireJS: How do I pass variables from one file to another? - Stack Overflow

I'm using require with backbone + backbone-forms. I'm currently using RequireJS to seperate c

I'm using require with backbone + backbone-forms. I'm currently using RequireJS to seperate code into multiple files. I have models stored in separate files and want to keep form validators separately.

However, I am unable to access variables defined in one files, in another file that depends on this one. What I get is Uncaught ReferenceError: isEmptyName is not defined. isEmptyName is defined in validators and used in model. Any feedback about RequireJS config is also appreciated.

My config:

requirejs.config({

//By default load any module IDs from js/lib

baseUrl: 'js',

paths: {
     jquery: 'lib/jquery',
        app: 'lib/app', 
     wizard: 'lib/jquery.bootstrap.wizard.min',
  bootstrap: 'lib/bootstrap.min',
 underscore: 'lib/underscore-min',
   backbone: 'lib/backbone-min',
backboneForms: 'lib/backbone-forms.min',
langSwitcher: 'lib/lang',
     cookie: 'lib/cookie',
 datepicker: 'lib/bootstrap-datepicker',
       mask: 'lib/jquery.maskedinput.min',
 validators: 'modules/validators',  

  // models

personalData: 'models/personal-data',
addressData: 'models/address-data',
   workData: 'models/work-data',
productsData: 'models/products-data',
statmentData: 'models/statment-data',    

     model: 'models/form',
collection: 'collections/form',
      view: 'views/form',

     setup: 'setup',
      send: 'send',

},
    shim: {
    'underscore': {
        deps: ['jquery'],
        exports: '_'
    },  
    'backbone': {
        deps: ['underscore', 'jquery'],
        exports: 'backbone'
    },

    // all model needs to go within one collection

    'bootstrap' : ['jquery'],
    'wizard': ['jquery'],
    'backboneForms': ['backbone'],
    'validators': ['backbone','mask'],
    'personalData' : ['backbone','backboneForms','validators'],
    'addressData': ['backbone','backboneForms'],
    'workData': ['backbone','backboneForms'],
    'statmentData': ['backbone','backboneForms'],

    //'collection': ['backbone','backboneForms','personalData'],
    //'view': ['backbone','backboneForms','personalData']
 } 
});

Beginning of validators.js

require(['backbone','backboneForms'], function(){


var lettersOnly = /^[A-Za-zęóąśłżźćńĘÓĄŚŁŻŹĆŃ]+$/;
var lettersOnlyDash = /^[A-Za-zęóąśłżźćńĘÓĄŚŁŻŹĆŃ\-]+$/;
var err = {};
var errCh = {};
var errFormat = {};

var isEmptyName = function(value){
err = { message: 'Wpisz imię.'};
if (value.length === 0) return err;
};

Beginning of model.js that needs the validators in validators.js

require(['backbone','backboneForms','mask','validators'], function(backbone,backboneForms,mask,validators){

var PersonalData = Backbone.Model.extend({

schema: {
    first_name:{ 
        title: 'Imię',            
        validators: [isEmptyName, isLetter, minCharCount] //Accessing validators.js members here...
    }, ...

I'm using require with backbone + backbone-forms. I'm currently using RequireJS to seperate code into multiple files. I have models stored in separate files and want to keep form validators separately.

However, I am unable to access variables defined in one files, in another file that depends on this one. What I get is Uncaught ReferenceError: isEmptyName is not defined. isEmptyName is defined in validators and used in model. Any feedback about RequireJS config is also appreciated.

My config:

requirejs.config({

//By default load any module IDs from js/lib

baseUrl: 'js',

paths: {
     jquery: 'lib/jquery',
        app: 'lib/app', 
     wizard: 'lib/jquery.bootstrap.wizard.min',
  bootstrap: 'lib/bootstrap.min',
 underscore: 'lib/underscore-min',
   backbone: 'lib/backbone-min',
backboneForms: 'lib/backbone-forms.min',
langSwitcher: 'lib/lang',
     cookie: 'lib/cookie',
 datepicker: 'lib/bootstrap-datepicker',
       mask: 'lib/jquery.maskedinput.min',
 validators: 'modules/validators',  

  // models

personalData: 'models/personal-data',
addressData: 'models/address-data',
   workData: 'models/work-data',
productsData: 'models/products-data',
statmentData: 'models/statment-data',    

     model: 'models/form',
collection: 'collections/form',
      view: 'views/form',

     setup: 'setup',
      send: 'send',

},
    shim: {
    'underscore': {
        deps: ['jquery'],
        exports: '_'
    },  
    'backbone': {
        deps: ['underscore', 'jquery'],
        exports: 'backbone'
    },

    // all model needs to go within one collection

    'bootstrap' : ['jquery'],
    'wizard': ['jquery'],
    'backboneForms': ['backbone'],
    'validators': ['backbone','mask'],
    'personalData' : ['backbone','backboneForms','validators'],
    'addressData': ['backbone','backboneForms'],
    'workData': ['backbone','backboneForms'],
    'statmentData': ['backbone','backboneForms'],

    //'collection': ['backbone','backboneForms','personalData'],
    //'view': ['backbone','backboneForms','personalData']
 } 
});

Beginning of validators.js

require(['backbone','backboneForms'], function(){


var lettersOnly = /^[A-Za-zęóąśłżźćńĘÓĄŚŁŻŹĆŃ]+$/;
var lettersOnlyDash = /^[A-Za-zęóąśłżźćńĘÓĄŚŁŻŹĆŃ\-]+$/;
var err = {};
var errCh = {};
var errFormat = {};

var isEmptyName = function(value){
err = { message: 'Wpisz imię.'};
if (value.length === 0) return err;
};

Beginning of model.js that needs the validators in validators.js

require(['backbone','backboneForms','mask','validators'], function(backbone,backboneForms,mask,validators){

var PersonalData = Backbone.Model.extend({

schema: {
    first_name:{ 
        title: 'Imię',            
        validators: [isEmptyName, isLetter, minCharCount] //Accessing validators.js members here...
    }, ...
Share Improve this question edited May 14, 2014 at 9:23 Sharadh 1,3289 silver badges15 bronze badges asked May 14, 2014 at 8:13 Szymon DzumakSzymon Dzumak 1512 silver badges10 bronze badges 8
  • 1 You need to define the validators as AMD module that returns the isEmptyName in order to use it – chchrist Commented May 14, 2014 at 9:01
  • 1 While the question is quite similar to another, I think it will be helpful for people new to RequireJS to have this around as a 'link' to the more technically worded question here – Sharadh Commented May 14, 2014 at 9:16
  • Thanks for help.It had some impact but I'm getting a different error "Uncaught TypeError: Cannot read property 'length' of undefined" how would I rewrite this function in order to make it work? – Szymon Dzumak Commented May 14, 2014 at 9:18
  • Where does this error occur - line, file, etc. This means that whatever var you're trying to get the length of is undefined, which could be due to a variety of reasons. EDIT: If it's in value.length === 0 check if value is passed in by the caller. – Sharadh Commented May 14, 2014 at 9:26
  • 1 I might be stating the obvious, but Chrome/Webkit's javascript debugging is quite robust. Open the Sources tab and open up validator.js, place a breakpoint at that line. The Call Stack on the right pane should help you figure out who is calling that... – Sharadh Commented May 14, 2014 at 9:31
 |  Show 3 more ments

1 Answer 1

Reset to default 7

I think you're using require when what you really need is define. From When should I use require() and when to use define()?,

With define you register a module in require.js that you than can depend on in other module definitions or require statements. With require you "just" load/use a module or javascript file that can be loaded by require.js.


So here, you have some variables that are defined in one file, but are required to be accessed in another file. Seems like a 'Module', doesn't it? So now, you have two ways of using this file as a module:

  1. Conform to AMD-ness
  2. Conform to chaotic javascript global variable-ness

Using the AMD Approach

validators.js is now a module. Anybody wishing to use 'validator functions' can depend on this module to provide it for them. That is,

define(['backbone','backboneForms'], function(){

  var lettersOnly = /^[A-Za-zęóąśłżźćńĘÓĄŚŁŻŹĆŃ]+$/;

  var isEmptyName = function(value){
  err = { message: 'Wpisz imię.'};
  if (value.length === 0) return err;

  return {
    someVariable: lettersOnly,
    someFunction: isEmptyName
  }
};

You'll notice that the require has been replaced with define. Now, when somebody (model) depends on validator.js, they can access their dependencies as follows

require(['backbone','backboneForms','mask','validators'], 
  function(backbone, backboneForms, mask, validators) {

    var isEmptyNameReference = validators.someFunction;
    ...

Using shim

Check Requirejs why and when to use shim config, which references this link which says,

if we were to just add the backbone.js file to our project and list Backbone as a dependency from one of our modules, it wouldn’t work. RequireJS will load backbone.js, but nothing in backbone.js registers itself as a module with RequireJS. RequireJS will throw up its hands and say something like, “Well, I loaded the file, but I didn’t find any module in there.”

So, you could have your validator.js populate a global Validator namespace, and still use it the way we used it in the example above.

function(){
  var lettersOnly = /^[A-Za-zęóąśłżźćńĘÓĄŚŁŻŹĆŃ]+$/;
  var isEmptyName = function(value){
    err = { message: 'Wpisz imię.'};
    if (value.length === 0) return err;

  Globals.Validator = {
    someVariable: lettersOnly,
    someFunction: isEmptyName
  }
}();

Your config.js would then be,

shim: {
    'validator': {
        deps: ['backbone','backboneForms'],
        exports: 'Globals.Validator'
    },
  ...

Note that you can alias the namespace as you wish, but the alias is just a reference to the existing global object/namespace. This is helpful if you have, say, Foo.Bar.Foobar as your namespace, but want to refer to it as FB. Shimming, hence, is a way for non-AMD libraries to adapt to AMD usage. In this case, option 1 should be sufficient.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745001902a4605545.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信