I defined a module (for the code easy to read,I delete some unnecessary line..)
Here is my game.js
define(['util'], function (util) {
return {
createNew : function (setting) {
var game = {
intervalTrigger : function () {
return window.setInterval(function () {
score++;//how to read deal with this value?
}, 1000);
}
}
};
return game;
}
};
});
and use it in app.js:
require.config({
baseUrl: "./src",
});
requirejs(['util', 'game'],
function (util,game) {
var score = 0;
function startgame(level) {
var setting = {};
var g = game.createNew();
g.intervalTrigger();
}
startgame(0);
});
in my case, I need to createNew for few times, so the score can't be stored in the module.
so how to access score in the module game?
You need to define score as an actual module. For example:
define([], function() {
var gameStats = {
score: 0
};
return gameStats;
});
Now you just need to inject wherever you need to work with game stats.
create a get/set function and expose it in the game.js:
define(['util'], function (util) {
var score = 0;
return {
createNew : function (setting) {
var game = {
intervalTrigger : function () {
return window.setInterval(function () {
score++;//how to read deal with this value?
}, 1000);
}
getScore: function(){ return score;} //getting the score
setScore: function(value){score = value;} //setting the score
}
};
return game;
}
};
});
now here you can use:
require.config({
baseUrl: "./src",
});
requirejs(['util', 'game'],
function (util,game) {
var score = 0;
function startgame(level) {
var setting = {};
var g = game.createNew();
g.setScore(score); //setting the score
g.intervalTrigger();
}
startgame(0);
});
Related
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 6 years ago.
I have class below when I call printData I get this.collection is undefined.
How do I access this.collection from the prototype inside printData()? Or do i need to change the class structure. Actually the object returns function which intern returns object in hierarchy.
Thanks in advance!
Sample Class:
var DbProvider = (function () {
function DbProvider(db) {
var that = this; // create a reference to "this" object
that.collection = db;
}
DbProvider.prototype.create = function () {
return {
action: function () {
var y = {
printData: function () {
alert('Hello ' + this.collection.Name);
}
};
return y;
}
};
};
return DbProvider;
})();
Usage:
var a = new DbProvider({ "Name": "John" });
a.create().action().printData();
You could save the this reference and bind it to the printData function
var DbProvider = (function () {
function DbProvider(db) {
var that = this; // create a reference to "this" object
that.collection = db;
}
DbProvider.prototype.create = function () {
var self = this;
return {
action: function () {
var y = {
printData: function () {
alert('Hello ' + this.collection.Name);
}.bind(self)
};
return y;
}
};
};
return DbProvider;
})();
var a = new DbProvider({ "Name": "John" });
a.create().action().printData();
Or you could refactor a bit and move that to the outer scope of DbProvider and use that in printData
var DbProvider = (function () {
var that;
function DbProvider(db) {
that = this; // create a reference to "this" object
that.collection = db;
}
DbProvider.prototype.create = function () {
return {
action: function () {
var y = {
printData: function () {
alert('Hello ' + that.collection.Name);
}
};
return y;
}
};
};
return DbProvider;
})();
var a = new DbProvider({ "Name": "John" });
a.create().action().printData();
just need to keep track of the this pointer correctly, like this
var DbProvider = (function() {
function DbProvider(db) {
this.collection = db;
}
DbProvider.prototype.create = function() {
var self = this;
return {
action: function() {
var y = {
printData: function() {
alert('Hello ' + self.collection.Name);
}
};
return y;
}
};
};
return DbProvider;
})();
let dbProvider = new DbProvider({
Name: "test"
});
dbProvider.create().action().printData();
Keeping ES5 syntax and the call structure a solution would be:
var DbProvider = (function () {
function DbProvider(db) {
var that = this; // create a reference to "this" object
that.collection = db;
}
DbProvider.prototype.create = function () {
var that = this;
return {
action: function() {
var y = {
printData: function () {
console.log('Hello ' + that.collection.Name);
}
};
return y;
}
};
};
return DbProvider;
})();
Definitely not elegant but it works :)
If you do not want to change your structure, you can achieve this behavior if you change you functions to arrow functions.
var DbProvider = (function () {
function DbProvider(db) {
var that = this; // create a reference to "this" object
that.collection = db;
}
DbProvider.prototype.create = function() {
return {
action: () => {
var y = {
printData: () => {
alert('Hello ' + this.collection.Name);
}
};
return y;
}
};
};
return DbProvider;
})();
The way you are creating this "class" is definitely non standard. Let me know if you want an example of how to better structure it.
Te following code is fine:
var Pill = (function() {
var hideCheckPricesPill = function() {
$(HB.pillSearchBar.checkPrices).hide();
};
var hideAnyPill = function(pill) {
$(pill).hide();
};
var displaySearchBar = function() {
$("." + HB.pillSearchBar.hideSearchForm).removeClass(HB.pillSearchBar.hideSearchForm);
};
var isEditSearchPill = function(pill) {
if(pill === HB.pillSearchBar.editSearchText) {
hideCheckPricesPill();
}
else {
hideAnyPill(pill);
}
};
var isMobileSearch = function(pill) {
if(!$(pill).hasClass(HB.pillSearchBar.jsOpenMobileSearch)){
isEditSearchPill(pill);
displaySearchBar();
}
};
var addEventListenerOnPill = function(pill) {
$(pill).on('click', 'a', function() {
isMobileSearch(pill);
});
};
return {
addEventListenerOnPill: addEventListenerOnPill
}
})();
Is there a way to add a prototype functionality to one of the public functions so that it can be returned and initialized with the "new" key word?
I have a nested function that I want to call from outside.
var _Config = "";
var tourvar;
function runtour() {
if (_Config.length != 0) {
tourvar = $(function () {
var config = _Config,
autoplay = false,
showtime,
step = 0,
total_steps = config.length;
showControls();
$('#activatetour').live('click', startTour);
function startTour() {
}
function showTooltip() {
}
});
}
}
function proceed() {
tourvar.showTooltip();
}
$(document).ready(function () {
runtour();
});
I was hoping to call it by tourvar.showTooltip(); but I seem to be wrong :) How can I make showTooltip() available from outside the function?
since my previous answer was really a hot headed one, I decided to delete it and provide you with another one:
var _Config = "";
var tourvar;
// Module pattern
(function() {
// private variables
var _config, autoplay, showtime, step, total_steps;
var startTour = function() { };
var showTooltip = function() { };
// Tour object constructor
function Tour(config) {
_config = config;
autoplay = false;
step = 0;
total_steps = _config.length;
// Provide the user with the object methods
this.startTour = startTour;
this.showTooltip = showTooltip;
}
// now you create your tour
if (_Config.length != 0) {
tourvar = new Tour(_Config);
}
})();
function proceed() {
tourvar.showTooltip();
}
$(document).ready(function () {
runtour();
});
function outerFunction() {
window.mynestedfunction = function() {
}
}
mynestedfunction();
I'm having trouble with designing a class which exposes its actions through callbacks. Yes my approach works for me but also seems too complex.
To illustrate the problem I've drawn the following picture. I hope it is useful for you to understand the class/model.
In my approach, I use some arrays holding user defined callback functions.
....
rocket.prototype.on = function(eventName, userFunction) {
this.callbacks[eventName].push(userFunction);
}
rocket.prototype.beforeLunch = function(){
userFunctions = this.callbacks['beforeLunch']
for(var i in userFunctions)
userFunctions[i](); // calling the user function
}
rocket.prototype.lunch = function() {
this.beforeLunch();
...
}
....
var myRocket = new Rocket();
myRocket.on('beforeLunch', function() {
// do some work
console.log('the newspaper guys are taking pictures of the rocket');
});
myRocket.on('beforeLunch', function() {
// do some work
console.log('some engineers are making last checks ');
});
I'm wondering what the most used approach is. I guess I could use promises or other libraries to make this implementation more understandable. In this slide using callbacks is considered evil. http://www.slideshare.net/TrevorBurnham/sane-async-patterns
So, should I use a library such as promise or continue and enhance my approach?
var Rocket = function () {
this.timer = null;
this.velocity = 200;
this.heightMoon = 5000;
this.goingToMoon = true;
this.rocketStatus = {
velocity: null,
height: 0,
status: null
};
this.listener = {
};
}
Rocket.prototype.report = function () {
for (var i in this.rocketStatus) {
console.log(this.rocketStatus[i]);
};
};
Rocket.prototype.on = function (name,cb) {
if (this.listener[name]){
this.listener[name].push(cb);
}else{
this.listener[name] = new Array(cb);
}
};
Rocket.prototype.initListener = function (name) {
if (this.listener[name]) {
for (var i = 0; i < this.listener[name].length; i++) {
this.listener[name][i]();
}
return true;
}else{
return false;
};
}
Rocket.prototype.launch = function () {
this.initListener("beforeLaunch");
this.rocketStatus.status = "Launching";
this.move();
this.initListener("afterLaunch");
}
Rocket.prototype.move = function () {
var that = this;
that.initListener("beforeMove");
if (that.goingToMoon) {
that.rocketStatus.height += that.velocity;
}else{
that.rocketStatus.height -= that.velocity;
};
that.rocketStatus.velocity = that.velocity;
if (that.velocity != 0) {
that.rocketStatus.status = "moving";
}else{
that.rocketStatus.status = "not moving";
};
if (that.velocity >= 600){
that.crash();
return;
}
if (that.rocketStatus.height == 2000 && that.goingToMoon)
that.leaveModules();
if (that.rocketStatus.height == that.heightMoon)
that.landToMoon();
if (that.rocketStatus.height == 0 && !that.goingToMoon){
that.landToEarth();
return;
}
that.report();
that.initListener("afterMove");
that.timer = setTimeout(function () {
that.move();
},1000)
}
Rocket.prototype.stop = function () {
clearTimeout(this.timer);
this.initListener("beforeStop");
this.velocity = 0;
this.rocketStatus.status = "Stopped";
console.log(this.rocketStatus.status)
this.initListener("afterStop");
return true;
}
Rocket.prototype.crash = function () {
this.initListener("beforeCrash");
this.rocketStatus.status = "Crashed!";
this.report();
this.stop();
this.initListener("afterCrash");
}
Rocket.prototype.leaveModules = function () {
this.initListener("beforeModules");
this.rocketStatus.status = "Leaving Modules";
this.initListener("afterModules");
}
Rocket.prototype.landToMoon = function () {
this.initListener("beforeLandToMoon");
this.rocketStatus.status = "Landing to Moon";
this.goingToMoon = false;
this.initListener("afterLandToMoon");
}
Rocket.prototype.landToEarth = function () {
this.initListener("beforeLandToEarth");
this.stop();
this.rocketStatus.status = "Landing to Earth";
this.initListener("afterLandToEarth");
}
Rocket.prototype.relaunch = function () {
this.initListener("beforeRelaunch");
this.timer = null;
this.velocity = 200;
this.heightMoon = 5000;
this.goingToMoon = true;
this.rocketStatus = {
velocity: 200,
height: 0,
status: "relaunch"
};
this.launch();
this.initListener("afterRelaunch");
}
init;
var rocket = new Rocket();
rocket.on("afterLaunch", function () {console.log("launch1")})
rocket.on("afterLandToMoon", function () {console.log("land1")})
rocket.on("beforeLandToEarth", function () {console.log("land2")})
rocket.on("afterMove", function () {console.log("move1")})
rocket.on("beforeLaunch", function () {console.log("launch2")})
rocket.launch();
You can add any function before or after any event.
This is my solution for this kinda problem. I am not using any special methods anything. I was just wonder is there any good practise for this like problems. I dig some promise,deferred but i just can't able to to this. Any ideas ?
I'm having a problem using the module pattern in a very dummy javascript code.
This code is working perfectly:
;
var test = (function () {
var config = {
replacement: 'a'
};
var init = function () {
$(config.replacement).click(function(){
alert("hello world");
});
}
return {
init: init
}
})();
$(document).ready(test.init());
Instead, this code is not working when I click on any link of my website:
;
var test = (function () {
var config = {
replacement: $('a')
};
var init = function () {
config.replacement.click(function(){
alert("hello");
});
}
return {
init: init
}
})();
$(document).ready(test.init());
Anyone could tell me why I can not use a jQuery object as "default" initialization of config variable.
The $(a) is executed before DOM ready, probably when no a elements are accessible.
In your first example, the set was constructed after DOM ready.
You could turn it into a function instead...
var config = {
replacement: function() { return document.links; }
};
Then, Why in this example located in official jQuery website using a jQuery selector is working for the default config vars?
var feature = (function () {
var $items = $("#myFeature li");
var $container = $("<div class='container'></div>");
var $currentItem = null;
var urlBase = "/foo.php?item=";
var createContainer = function () {
var $i = $(this);
var $c = $container.clone().appendTo($i);
$i.data("container", $c);
},
buildUrl = function () {
return urlBase + $currentItem.attr("id");
},
showItem = function () {
$currentItem = $(this);
getContent(showContent);
},
showItemByIndex = function (idx) {
$.proxy(showItem, $items.get(idx));
},
getContent = function (callback) {
$currentItem.data("container").load(buildUrl(), callback);
},
showContent = function () {
$currentItem.data("container").show();
hideContent();
},
hideContent = function () {
$currentItem.siblings().each(function () {
$(this).data("container").hide();
});
};
$items.each(createContainer).click(showItem);
return {
showItemByIndex: showItemByIndex
};
})();
$(document).ready(function () {
feature.showItemByIndex(0);
});
Official jQuery website