Here is the my question
var panel = {
_pnlHeaderContainer: $('.panelHeader'),
_pnlHeaderString:"",
//private method
_Write: function (pnlHeaderString) { return this._pnlHeaderContainer.html(pnlHeaderString); },
Clear: function () { return this._pnlBaslikContainer.html(""); },
// _fake:this,
Header: {
AddEvent:"Add Event",
Calendar: "Calendar",
}
};
what I wanna achieve is using the _Write method in Header object
something like this
Header: {
AddEvent:this._Write("Add Event"),
Calendar: "Calendar",
}
trying to run this code like this panel.Header.AddEvent; but it says me Write is not a function
I like to provide a context when creating a class
function Panel(){
var context = this;
this._pnlHeaderContainer = $('.panelHeader');
this._pnlHeaderString = "";
this._Write = function(pnlHeaderString){
return context._pnlHeaderContainer.html(pnlHeaderString);
};
this.Clear = function(){
return context._pnlBaslikContainer.html("");
};
this.Header = {
AddEvent: function(){ return context._Write("Add Event"); },
Calendar: "Calendar",
};
}
var panelObject = new Panel();
// Do whatever you want...
panelObject.Header.AddEvent();
Related
I have my javascript code like this . Inside that I have an init() function and in that function I have an options JSON object and in that object I have a function defined as objectselected(). How I call that function in a button click event
I have tried like this WorkFlow.init().options.Objectselected() but it is not working,
var WorkFlow = {
connectionData: [],
selectedTouchpoints: [],
init: function () {
var options = {
palleteId: "myPaletteElement",
elementId: "playAreaContainer",
TextStoreList: ['One', 'Two', 'Three'],
LinkTextStoreList: $('#drpLinkType option').map(function () {
return this.text;
}).get(),
shapeList: ['RoundedRectangle', 'Circle', 'Rectangle', 'Ellipse', 'Square', 'Diamond', 'Card', 'Database'],
diagramUpdate: function (e) {
},
objectSelected: function (e) {
},
linkUpdate: function (e) {
},
initialize: function () {
}
myGraph = new Graph(options);
options.initialize();
},
}
How to call that function.
One way around is you can return options and than call it.
init: function () {
var options = {
...your code..}
return options;
},
and call it than
var options = WorkFlow.init();
options.Objectselected();
As it stands, you have no access to options because it's a local variable - that is, local to its scope.
To access its contents, you'll need to return it from init().
Think about it:
WorkFlow.init()
Currently this returns undefined, because your init() returns nothing. You're trying to chain like in jQuery, but that relies on the API always returning the instance. Your path finds a dead-end at init().
To fix this, have init() return options - or at least the part of it you want to access from outside - an "export".
So (basic example)
init: function() {
var options {
my_func: function() { }, //<-- we want outside access to this
private: 'blah' //<-- this can stay private - leave it out of the export
}
//return an export, exposing only what we need to
return {
my_func: options.my_func
}
}
You need to return options as it is inside init function's scope
var WorkFlow = {
connectionData: [],
selectedTouchpoints: [],
init: function () {
var options = {
palleteId: "myPaletteElement",
elementId: "playAreaContainer",
TextStoreList: ['One', 'Two', 'Three'],
LinkTextStoreList: $('#drpLinkType option').map(function () {
return this.text;
}).get(),
shapeList: ['RoundedRectangle', 'Circle', 'Rectangle', 'Ellipse', 'Square', 'Diamond', 'Card', 'Database'],
diagramUpdate: function (e) {
},
objectSelected: function (e) {
},
linkUpdate: function (e) {
},
initialize: function () {
}
myGraph = new Graph(options);
options.initialize();
return options;
},
}
And call it as WorkFlow.init().objectSelected();
Building on Patrick's comment, you'd need to return options from the init function:
var WorkFlow = {
connectionData: [],
selectedTouchpoints: [],
init: function () {
var options = {
palleteId: "myPaletteElement",
...
options.initialize();
return options;
},
}
Suppose I have a class (let's say, LinkedListNode.js) defined below:
// LinkedListNode.js
define([
"dojo/_base/declare"
] , function (declare) {
return declare(null, {
constructor: function(data) {
this._data = data;
},
addNext: function(data) {
}
});
});
How can I instantiate an instance of this class within its own definition, like below:
// LinkedListNode.js
define([
"dojo/_base/declare"
] , function (declare) {
return declare(null, {
constructor: function(data) {
this._data = data;
},
addNext: function(data) {
this._next = new LinkedListNode(data);
}
});
});
Here is an example of what I am trying to do in Java:
class LinkedListNode {
private int data;
private LinkedListNode next;
public LinkedListNode(int data) {
this.data = data;
}
public void addNext(int data) {
// How can I execute this same statement in JavaScript/Dojo?
this.next = new LinkedListNode(data);
}
}
You don't do it like that in Dojo. You just put your new class in the define section of the place you want to use it and Dojo makes the instatiation for you. So if you saved on Object.js, you would use it like this:
define([
"dojo/_base/declare",
"yourpath/Object"
] , function (declare, object) {
return declare(null, {
constructor: function() {
},
test: function() {
object.whatever();
}
});
});
Complemented based on edits
Well to use the way you want, you can't do it with dojo's declare system. You have to do it in the more traditional way. Js is a free free language, you can do things in many ways. So you have several methods to do something like that in JS. Here are 3:
function LinkedListNode(data) {
this.addNext = function(data) {
this.next = new LinkedListNode(data);
return this.next;
}
this.data = data;
}
var ll1 = new LinkedListNode(777);
ll1.addNext(555).addNext(333);
console.log(ll1.next.data);
console.log(ll1.next.next.data);
function LinkedListNodeV2(data) {
var self = {}
self.addNext = function(data) {
self.next = new LinkedListNodeV2(data);
return self.next;
}
self.data = data;
return self
}
var ll2 = LinkedListNodeV2(777);
ll2.addNext(555).addNext(333);
console.log(ll2.next.data);
console.log(ll2.next.next.data);
class LinkedListNodeV3 {
constructor(data) {
this.data = data;
}
addNext(data) {
this.next = new LinkedListNodeV3(data);
return this.next;
}
}
var ll3 = new LinkedListNodeV3(777);
ll3.addNext(555).addNext(333);
console.log(ll3.next.data);
console.log(ll3.next.next.data);
JSFiddle: https://jsfiddle.net/s1pemgbk/2/
But how do you put that in Dojo ? as allways in JS there are many ways, one of them is this:
// LinkedListHelper.js
define([
"dojo/_base/declare"
] , function (declare) {
class LinkedListNode {
constructor(data) {
this.data = data;
}
addNext(data) {
this.next = new LinkedListNode(data);
return this.next;
}
};
var self = {};
self.getLLInstance = function(data) {
return new LinkedListNode(data);
}
return self;
});
then you would use it like this:
define([
"dojo/_base/declare",
'project/helpers/linkedListHelper',
], function (
declare,
linkedListHelper
) {
return declare([_WidgetBase, _TemplatedMixin], {
postCreate: function () {
this.inherited(arguments);
var ll = linkedListHelper.getLLInstance(777);
ll.addNext(555).addNext(333);
console.log(ll.next.data);
console.log(ll.next.next.data);
}
});
});
Hope it's clearer now :)
As you can see in this example, two dojo classes are created using dojo module declare. Dojo abstracts classes similarly to Java.
When a class is defined using define you can initiate it in your code at will.
In this example YourMainClass's constructor contains a reference to an instance of YourClass were it was initiated.
Live demo here:
https://jsfiddle.net/gibbok/uw17etqg/
require(["dojo/_base/declare", "dojo/_base/lang"], function(declare, lang) {
var YourClass = declare(null, {
constructor: function(name, age, residence) {
this.name = name;
this.age = age;
this.residence = residence;
},
print: function() {
alert(this.name);
}
});
var YourMainClass = declare(null, {
constructor: function(name, age, residence) {
this.yourClassInstance = new YourClass('foo', 'bar', 'zoo');
this.yourClassInstance.print();
}
});
var yourMainClass = new YourMainClass();
});
I have a factory like this:
TestFactory= function () {
var objectName=null;
return {
SetName:function(name) {
objectName = name;
},
GetName:function() {
return objectName;
},
Init:function() {
return angular.copy(this);
}
}
}
A controller like:
TestController = function($scope) {
$scope.TestClick = function () {
var tstA = TestFactory.Init();
var tstB = TestFactory.Init();
tstA.SetName('test A')
tstB.SetName('test B')
console.log('A', tstA.GetName());
console.log('B', tstB.GetName());
}
}
In the console I get Test B for both objects.
How can I make a proper instance of this object?
I would like to use the objectName value in other functions of the factory.
Take into account that in Angular, Factories are singletons, so the instance is always the same.
You can do the following:
TestFactory= function () {
var objectName={};
return {
SetName:function(property,name) {
objectName[property] = name;
},
GetName:function(property) {
return objectName[property];
},
Clear:function(property) {
delete objectName[property]
}
}
}
Then in your controller:
TestController = function($scope, TestFactory) {
$scope.TestClick = function () {
TestFactory.SetName('a','test A')
TestFactory.SetName('b','test B')
console.log('A', TestFactory.GetName('a')); // test A
console.log('B', TestFactory.GetName('b')); // test B
}
}
Couple of issues. First your returning an object rather than a function from your factory.
app.factory('TestFactory', function() {
return function() {
var objectName = null;
var setName = function(name) {
objectName = name;
};
var getName = function() {
return objectName;
};
return {
SetName: setName,
GetName: getName
};
};
});
Then you can just instantiate like this:
var tstA = new TestFactory();
var tstB = new TestFactory();
Services and factories are singletons so I think you can achieve what you want with a more appropriate use of the factory by providing an Init function that returns the common code and unique name like so:
angular.module('app')
.factory('ServiceFactory', serviceFactory);
function serviceFactory() {
return {
Init: function (name) {
return {
objectName: name,
setName: function (name) {
this.objectName = name;
},
getName: function () {
return this.objectName;
}
};
}
};
}
This leaves the possibility to use it as a factory that can initialize many types.
You basically need to create a simple getter/setter.
angular.module('app', [])
.controller('TestController', testController)
.service('serviceFactory', serviceFactory);
testController.$inject = ['serviceFactory'];
function testController(serviceFactory) {
serviceFactory.set('A', {
name: 'test A'
});
serviceFactory.set('B', {
name: 'test B'
});
console.log(serviceFactory.getAll());
console.log(serviceFactory.get('A'));
console.log(serviceFactory.get('B'));
}
function serviceFactory() {
var
_model = {
name: ""
},
_data = {};
return {
set: function(key, data) {
_data[key] = angular.extend({}, _model, data);
},
get: function(key) {
return _data[key];
},
getAll: function() {
return _data;
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<body ng-app="app" ng-controller="testController"></body>
I have the following code:
{
data: function () {
return {
questions: [],
sendButtonDisable: false,
}
},
methods: {
postQuestionsContent: function () {
var that = this;
that.sendButtonDisable = true;
},
},
},
I need to change sendButtonDisable to true when postQuestionsContent() is called. I found only one way to do this; with var that = this;.
Is there a better solution?
Inside methods if you don't have another scope defined inside, you can access your data like that:
this.sendButtonDisable = true;
but if you have a scope inside the function then in vue is a common usage of a variable called vm (stands for view model) at the beginning of the function, and then just use it everywhere like:
vm.sendButtonDisable = false;
An example of vm can be seen in the Vue official documentation as well.
complete example:
data: function () {
return {
questions: [],
sendButtonDisable : false
}
},
methods: {
postQuestionsContent : function() {
// This works here.
this.sendButtonDisable = true;
// The view model.
var vm = this;
setTimeout(function() {
// This does not work, you need the outside context view model.
//this.sendButtonDisable = true;
// This works, since wm refers to your view model.
vm.sendButtonDisable = true;
}, 1000);
}
}
It depends on how you call your postQuestionsContent method (if you call it asynchronously, you might need to bind the this context).
In most cases, you should be able to access it using this.$data.YOURPROPNAME, in your case this.$data.sendButtonDisable:
data: function () {
return {
questions: [],
sendButtonDisable : false
}
},
methods:
{
postQuestionsContent : function()
{
this.$data.sendButtonDisable = true;
}
}
Try this instead
...
methods:
{
postQuestionsContent ()
{
this.sendButtonDisable = true;
}
}
Registering your methods in the above manner should resolve the issue.
I tried both this.$data.sendButtonDisable and vm.sendButtonDisable and did not work for me.
But I got it working with outer_this = this, something like:
methods: {
sendForm(){
var outer_this;
outer_this = this;
$.ajax({
url: "email.php",
type: "POST",
dataType: "text",
data: {
abc: "..."
},
success: function(res){
if(res){
//...
outer_this.sendButtonDisable = false;
}else{
//...
}
}
});
}
},
I need to remake this functoin 'i18n' to a factory but so i return a value instead of just setting it with this.
Thanks in advance!
services.service('i18n', function() {
var self = this;
this.setLanguage = function(language) {
$.i18n.properties({
name: 'messages',
path: 'i18n/',
mode: 'map',
language: language,
callback: function() {
self.language = language;
}
});
};
this.setLanguage('nl');
});
Try to set up your service like this:
myApp.service('LangService', function() {
var setLang = function(lang) {
// return whatever you want
}
return {
setLang: setLang
};
});
Then you can call your method setLang from anywhere:
LangService.setLang('nl');