Am building a single page site with backbone.js. Am using require.js to make the code modular,
but am having problems initializing the backbone router for urls.
I load the main js file using require.js, heres what it looks like
enter code here
//App Namespace
var Chrono = Chrono || {};
//App Config Namespace
Chrono.Config = Chrono.Config || {};
//App Views Namespace
Chrono.Views = Chrono.Views || {};
//Config
Chrono.Config = {
url:"http://localhost/chronotech/",
site_url:"http://localhost/chronotech/index.php/",
data_source:"http://localhost/chronotech/assets/datasource/"
};
require.config({
paths : {
'backbone': 'libs/backbone',
'jquery':'libs/jquery.min',
'underscore':'libs/underscore',
'text':'libs/require/text'
},
baseUrl : 'assets/js'
});
require(
['require', 'underscore', 'backbone', 'jquery'],
function(require,_, Backbone, $) {
require(['app'],
function(require) {
} );
} );
And the app.js looks like this
define(['backbone','routers/workspace'],
function( Backbone,Workspace) {
$(function () {
var space = new Workspace();
} );
} );
And router file looks like this
define(['jquery','backbone'],
function($, Backbone) {
var Workspace = Backbone.Router.extend( {
routes: {
"about":"aboutPage",
"team":"teamPage",
"contact":"contactPage",
"work":"portfolioPage",
"products":"productPage"
},
aboutPage : function() {
alert("about");
},
teamPage : function() {
alert("team");
},
contactPage: function() {
alert("contact");
},
portfolioPage : function() {
alert("work");
},
productPage : function() {
}
} );
return Workspace;
} );
When i load the page, i get the following errors:
"Uncaught ReferenceError: $ is not defined",
"Uncaught TypeError: Cannot read property 'Router' of null".
What am i doing wrong?
define(['backbone','routers/workspace'],
function( Backbone,Workspace) {
$(function () {
var space = new Workspace();
} );
} );
Is it a separate file? Maybe you need to load jQuery in order to use $?
Related
Here i'm trying to extend Amasty js widget in my module using mixin.
I have created requirejs-config.js file like below
var config = {
config: {
mixins: {
'amShopbyAjax': {
'vendor_CustomCatalog/js/amasty/amShopbyAjax-override': true
}
}
}
};
I have created js file like below
define([
"jquery",
"jquery-ui-modules/widget"
], function ($) {
'use strict';
var amShopbyWidgetMixin = {
selectors: {
category_products_wrapper: '#amasty-shopby-category-product-list',
},
reloadHtml: function (data) {
console.log("Sdfsdfsdf");
return this._super();
},
callAjax: function (clearUrl, data, pushState, cacheKey, isSorting) {
console.log("sdnjkasndnsadj");
return this._super();
}
};
return function (targetWidget) {
$.widget('custom.amShopbyAjax', targetWidget, amShopbyWidgetMixin);
return $.custom.amShopbyAjax;
};
});
After that I ran sudo bin/magento setup:static-content:deploy -f and clear cache then I am getting "Uncaught TypeError: base is not a constructor" error
Think that you should change custom.amShopbyAjax to mage.amShopbyAjax
return function (targetWidget) {
$.widget('mage.amShopbyAjax', targetWidget, amShopbyWidgetMixin);
return $.mage.amShopbyAjax;
};
The widget alias should be like for the target widget and the widget by parent alias should be returned
i have the following scenario:
i have a global namespace called fort which has a few common functions that i need and it looks like this :
fort.js
define("fort", ["fortHistory"], function (FortHistory) {
function Fort(){}
Fort.prototype.history = FortHistory;
return Fort;
});
fortHistory is a small module i created defined as so:
fortHistory.js
"use strict";
define("fortHistory", function () {
function FortHistory() {
}
FortHistory.prototype.doSomething = function(){...}
return FortHistory;
});
i then do this in my config.js
require.config( {
enforceDefine: true,
paths: {
'fort': 'develop/js/fort',
'fortHistory' : 'develop/js/webapp/fortHistory'
},
shim: {
fort:{
exports: 'fort'
}
}
} );
define( function() {} );
finally in main.js i have:
define('fort', [], function(fort){
window.fort = fort;
});
the hope was that i could then make a call such as :
fort.fortHistory.doSomething();
instead fort is undefined so i am assuming i have misinterpreted how requirejs works
You've named it history, not fortHistory:
Fort.prototype.history = FortHistory;
Try calling it via fort.history.doSomething();.
I've set up an app with react using react-router for routing and are having issues bundling it all.
I'm trying to build/bundle all the js files using gulp-requirejs. But somehow the shim is not included, or the react-router is just ignored. Whatever the problem is, I just end up with an error in the browser console saying Uncaught Error: app missing react-router
I'm including the most important code, feel free to ask if something doesn't make sense.
gulpfile.js
Almond.js is there to replace requirejs
var gulp = require('gulp'),
uglify = require('gulp-uglify'),
rjs = require('gulp-requirejs'),
gulp.task('requirejsBuild', function() {
rjs({
baseUrl: './app/resources/js/',
out: 'app.min.js',
paths: {
'react': '../bower_components/react/react-with-addons',
'react-router': '../bower_components/react-router/dist/react-router',
'react-shim': 'react-shim',
'jquery': '../bower_components/jquery/dist/jquery'
},
shim: {
'react-shim': {
exports: 'React'
},
'react-router': {
deps: ['react-shim']
}
},
deps: ['jquery', 'react-router'],
include: ['init'],
name: '../bower_components/almond/almond'
})
.pipe(uglify()).pipe(gulp.dest('./app/resources/js/'));
});
init.js
require.config({
baseUrl: '/resources/js/',
deps: ['jquery'],
paths: {
'react': '../bower_components/react/react-with-addons',
'react-router': '../bower_components/react-router/dist/react-router',
'react-shim': 'react-shim',
'jquery': '../bower_components/jquery/dist/jquery'
},
shim: {
'react-shim': {
exports: 'React'
},
'react-router': {
deps: ['react-shim']
}
}
});
require(['react', 'app'], function(React, App) {
var app = new App();
app.init();
});
app.js
define([
'react',
'react-router',
], function(
React,
Router,
){
var Route = Router.Route;
var RouteHandler = Router.RouteHandler;
var DefaultRoute = Router.DefaultRoute;
/**
* Wrapper for it all
*
* #type {*|Function}
*/
var Wrapper = React.createClass({displayName: "Wrapper",
mixins: [Router.State],
render: function() {
return (
React.createElement(RouteHandler, null)
);
}
});
var routes = (
React.createElement(Route, {handler: Wrapper, path: "/"}, null)
);
var App = function(){};
App.prototype.init = function () {
Router.run(routes, Router.HistoryLocation, function (Handler) {
React.render(React.createElement(Handler, null), document.getElementById('content'));
});
};
return App;
}
);
index.html
Mainly containing a script tag
After build you have to manually swap the src with app.min.js
<script data-main="/resources/js/init" src="/resources/bower_components/requirejs/require.js"></script>
This is from knockout.dirtyFlag.js
;(function (ko) {
ko.DirtyFlag = function (objectToTrack, isInitiallyDirty, hashFunction) {
hashFunction = hashFunction || ko.toJSON;
var
_objectToTrack = objectToTrack,
_lastCleanState = ko.observable(hashFunction(_objectToTrack)),
_isInitiallyDirty = ko.observable(isInitiallyDirty),
result = function () {
var self = this;
self.isDirty = ko.computed(function () {
return _isInitiallyDirty() || hashFunction(_objectToTrack) !== _lastCleanState();
});
self.reset = function () {
_lastCleanState(hashFunction(_objectToTrack));
_isInitiallyDirty(false);
};
return self;
};
return result;
};
})(ko);
In my model I have a define setup like this:
define([
"lib/knockout",
"lib/knockout.dirtyFlag"
],
function(ko) {
...
self.dirtyFlag = new ko.DirtyFlag([
}
basically I get an error saying that DirtyFlag is undefined.
What do I need to do?
Well, looks like I got it working, so I'll post my findings:
In my requirejs config I added this:
shim: {
"lib/knockout/knockout.dirtyFlag": {
deps: [
"lib/knockout/knockout"
],
init: function (ko) {
var self = this;
ko.DirtyFlag = self.ko.DirtyFlag;
return ko;
}
}
I'm not very familiar with javascript or requirejs, but init seems to put the dep in "ko" and then I am able to create a DirtyFlag on ko. self.ko.DirtyFlag is the actual knockout.dirtyFlag javascript.
You are requiring lib/knockout and lib/knockout.dirtyFlag. Do you need both ?
If you need both, try:
define([
"lib/knockout",
"lib/knockout.dirtyFlag"
],
function(ko, kodf) {
...
self.dirtyFlag = new kodf.DirtyFlag([
}
You could also try:
define([
"lib/knockout",
"lib/knockout.dirtyFlag"
],
function(k) {
...
self.dirtyFlag = new ko.DirtyFlag([
}
As I think you are defining ko in the require as well as in knockout.dirtyFlag.
I have ended with wrapping kolite classes with define methods. Below example with command, but it will be same for others.
requirejs.config({
paths: {
knockout: 'Scripts/libs/knockout/knockout-2.2.1.debug',
command: 'Scripts/libs/knockout/knockout.command'
},
shim: {
knockout: {
exports: 'ko'
},
command: {
deps: ['knockout'],
exports: 'ko'
}
});
And wrapped command
define(['knockout'], function(ko) {
... // command original code
return ko;
)
in my module
define(['command'], function (ko) {
var doYourStaff = 0;
return doYourStaff;
});
We have added support for RequireJS for all three libs now, you can use the latest version from master.
All my deps are being found and loaded, but my Application which is the mapApp.js file is never found and always gives me a Undefined when I try to use it.
What am I doing wrong ?
this is my folder hierarchic
Site
|
|- JS
|- Libs
| |- * All my deps *
|
|- mapApp.JS
|
.
.
.
|- /models
|- /views
|- /collections
This is my Main.js file that initialize require.js
require.config({
baseUrl: '/ctt-ct/js/'
,urlArgs: "ts=" + (new Date()).getTime()
,paths: {
'jquery': 'libs/jquery.min'
,'underscore': 'libs/underscore-min'
,'backbone': 'libs/backbone'
,'templates': '../templates'
}
,shim: {
jquery: {
exports: '$'
}
,underscore: {
exports: '_'
}
,backbone: {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
}
}
});
require([
'jquery'
,'underscore'
,'backbone'
,'mapApp'
],
function ($, _, Backbone, App) {
$; // <- working
_; // <- working
Backbone.View; // <- working
var app = new App(); // <- NOT working !!!
});
mapApp.js
require([
'jquery'
,'underscore'
,'backbone'
],
function ($, _, Backbone) {
var App = Backbone.View.extend({
el : $('#map_canvas')
,initialize : function(){
// DO a lot of stuff and don't return anything.
}
,drawData: function(){
// Do other stuff.
}
});
});
You must return App from the function :
...
function ($, _, Backbone) {
var App = Backbone.View.extend({
});
return App;
});
Usually, I don't use it require like that, but I'm absolutely not sure of the correct way (the documentation is not very friendly). I would write often :
mapApp.js
define([
'views/otherView' //Other BackboneView
],
function (OtherView) {
var App = Backbone.View.extend({
el : $('#map_canvas')
,initialize : function(){
// stuff ; not too much in a View
}
,render : function(){
var otherView = new OtherView();
...
return this;
}
});
return App;
});
In that case, Backbone, Underscore and jQuery are global variables in the page. I think it make sense as you always need them.