requirejsdurandal

Which RequireJS syntax is correct in Durandal?


I'm very new to Durandal, but think it's great framework considering my background in jQuery and a little KnockoutJS, however I've come across what appears to be two different methods of using RequireJS withing Durandal.

In the Durandal samples the following syntax is used: Durandal / App / samples / modal / index.js

    define(['durandal/app', './customModal'], function (app, CustomModal) {

    return {
        showCustomModal: function() {
            app.showModal(new CustomModal()).then(function(response) {
                app.showMessage('You answered "' + response + '".');
            });
        }
    };
});

Here the dependencies/requirements (is that the right word here?) are defined as the first argument of the call to define (['durandal/app', './customModal']).

In the Durandal documentationthe following syntax is used:Creating a Module

define(function(require){
  var backend = require('backend');

  return {
    customers:ko.observableArray([]),
    activate:function(){
      var that = this;
      return backend.getCustomers().then(function(results){
        that.customers(results);
      });
    }
  };
});

Here only the function is passed to the call to define, with require as a dependency/requirement of that function. The require function is then called to get the actual dependency/requirement (var backend = require('backend');) that is needed.

Coming from a .net IoC background the first seems correct, define my requirements and let the requirejs framework locate the dependencies for me, and the second seems like the service locator anti pattern.

Is my interpretation of these two methods correct, should the first one be used, and the documentation is wrong(!)?

If not, what are the pros/cons of these two methods? Which one is advisable to use and why?

Many thanks


Solution

  • I think whichever way you like best is the way to go. I think requirejs made it so you can do both ways so it can support commonjs module format.

    According to requirejs' site if you use the way durandal is resolving its dependencies:

    define(function(require) { var app = require('durandal/app');  app.start(); }
    

    "This wrapper relies on Function.prototype.toString() to give a useful string value of the function contents. This does not work on some devices like the PS3 and some older Opera mobile browsers." --quoted from requirejs

    But that is an edge case which I don't think too many people care about. Other than that.. I would just pick whichever one suites you best.

    I'm not sure what you mean by a service locator anti pattern. I'm pretty sure both ways are valid and anyway you choose to do it is purely for aesthetics.

    EDIT**

    Durandal is no longer using the above pattern for resolving its dependencies. It is now using this way:

    define(['./app','./system'], function (app, system) { //... });