I have code like this:
Ext.define( 'someClass', {
statics : {
methodA : function( ) { return 'A'; },
methodAB : function( ) {
var A = this.methodA();
return A + 'B';
}
}
} );
I have problem with accessing static methodA.
Can someone help me what would be a proper way to do it ?
you should call statics using the fully qualified className.methodName() syntax. 'this' inside a static is not going to be what you think it is. For example, if called from an event handler it will probably be the 'window' object, which certainly doesn't have a methodA() method. In other cases 'this' may be the prototype. In that case you may get away with this syntax but it is misleading and likely to cause future bugs.
Related
I've recently taken upon myself to add setter and getter methods to my class.
Since doing this, many parts of my code got broken and I'm unable to access getter methods.
Take the example below:
private loadInputs() : Input[] {
var inputs = <Input[]>this.get('inputs');
inputs.sort((a,b) => a.QuoteRef().localeCompare(b.QuoteRef()))
return( inputs || [] );
}
My input class has 2 variables,
_Project: string
_line: string
Which I access using a method QuoteRef()
public QuoteRef(): string {
return this._Project.concat('-' + this._Line.toString().padStart(3,'0'));
}
Whenever I try to access a method or a getter from my class on an item that is casted as an Input, I can see the variables (though not access them as they are private), but the prototype section doesn't contain any of the methods.
This triggers the following error in the website console:
TypeError: a.QuoteRef is not a function
What am I doing wrong?
Update
I got it to work by updating the code as follows:
inputs.sort((a,b) => {
let first = new Input(a);
let second = new Input(b);
return first.QuoteRef().localeCompare(second.QuoteRef());
});
Without seeing your complete class I can only guess, but I think that a and b in your sort are not of the type you expect. I can't see what this.get('inputs') does, but I suspect it is not returning an array with Input class objects. Hence the function cannot be found (is not a function). You could try:
inputs.sort((a,b) => {
console.log(typeof a);
console.log(typeof b);
a.QuoteRef().localeCompare(b.QuoteRef());
})
and check what the type is. Then check what your this.get actually returns.
Edit: forgot to mention that your IDE probably does not warn you because you cast the output of this.get to <Input[]>.
I am trying to understand the value of this at different points in a script. Questions similar to mine have been answered in this forum but those answers are considerably above my current learning level.
In my code experiments, I am using console.logs to return the this value. The value returned is always as expected, but the format of the returned value is inconsistent, which leads me to wonder why.
This code returns the expected Window object for the first 3 log commands to be executed but returns only the object literal for the 4th command, executed from the object's method.
var myName = {
name: "James",
sayName: function() {
console.log(this, 4);
console.log(this.name)
}
}
console.log(this, 1);
function myFunction() {
console.log(this, 2);
function nestFunction() {
console.log(this, 3);
myName.sayName();
}
nestFunction();
}
myFunction();
I have 3 questions: Why doesn't console.log return the name of the object? Is there a way to make it do so? Is there a simple way to do that other than console.log? Any help would be appreciated.
Ok I was going through your code to see what you specifically mean
here is the short explanation as to why THIS is different in some of the places
This keyword refers to the object it belongs to. Generally you used it to refer to the global window object .That's what is reflecting in your console log 1,2,3 .
Calling this in static javaScript object will return the javaScript object ,not the window object that is what is reflecting in the console.log(this,4).
So it gives you a way to call elements inside a static object .
Another way to understand this keyword is to look at constructors .The best example of the keyword
this
is inside a constructor function
var myObj = function(){
function myObj(ref)
{
this.name = "";
this.Item = "";
this.ref = ref;
this.speak();
}
myObj.prototype.speak =function()
{
this.name = 'James';
this.item = 'cheese';
console.log(this.ref)
//and the constuctor object
console.log(this)
}
return myObj;
}();
var e = new myObj('a Refrence string');
This should give you a basic understanding of how this works
here is more info to get you started Wschools.com
Please, help me solve the problem.
"no-use-before-declare" in tslint.json is true. And I am not allowed to change it.
The problem is following - "variable 'foo' used before declaration" build error.
The code may be simplified to:
export class One {
toSecond() : Two {
return new Two();
}
}
export class Two {
toFirst() : One {
return new One();
}
}
Could it be hacked somehow to overcome the linter warning and have the same result. Any workaround?
You could do:
let Two_forward: typeofTwo;
export class One {
toSecond() : Two {
return new Two_forward();
}
}
export class Two {
toFirst() : One {
return new One();
}
}
// Work around https://github.com/palantir/tslint/issues/3655
type typeofTwo = typeof Two;
Two_forward = Two;
but IMO this is unreasonable compared to just suppressing the lint error with // tslint:disable-next-line:no-use-before-declare. (And it might need further changes if the strictLocalInitialization option proposed here becomes part of strict.)
This was previously filed as a bug on tslint and the resolution was that classes are not hoisted and cannot be used before declaration. The rule is correct in this case.
Since I started to write code with AngularJS, I've been using factories and found them very useful.
I thought that they work like this (pseudo code):
FACTORY NAMESPACE {
PRIVATE FIELDS AND FUNCTIONS
RETURN {
INTERFACES TO ACCESS PRIVATE DATA
}
}
I thought that the expressions in return evaluates only when accessed directly, but, it seems that I didn't get it right.
I understand that the factories and services are very bottom of AngularJS and maybe someone thinks that this question shouldn't be here because it's trivial, and yet...
I created this plunk, I tried to find out why the variable changed inside factory code, won't keep its value after, when being accessed from outside, and what I found out confused me even more, the code inside of every return functions evaluates before anything else and it doesn't get called when it should be (by my logic)! Is. Is that designed that way, and if so, why?
Snippet from plnkr
var myApp = angular.module('app',[])
myApp.factory('_gl', [function () {
// Private fields
var _x;
function _somefunc(){
// This function evaluates even before the code of 'ctrl'
_x = 6;
console.log("changed:"+ _x);
}
return {
x:_x,
changeX:_somefunc()
}
}]);
myApp.controller('ctrl', ['_gl', function (_gl) {
_gl.x=2;
console.log("x init: " + _gl.x);
_gl.changeX(); // This does nothing at all
console.log("x after change: " + _gl.x);
}]);
/* Expected output
x init: 2
changed: 6
x after change:6
/*
/* Actual output
x init: 2
changed:6
x after change: 2
*/
Result:
After all that I found out from #dfsq (that right way is to use getters and setters), I came to the conclusion that although it can make some memory overhead, using simple JS global vars will do for me better.
the code inside of every return functions evaluates before anything else
Of course, because you are executing it with _somefunc().
It should be:
return {
x: _x,
changeX: _somefunc
}
Note, that there should be no () after _somefunc, which is invocation operator. You want changeX to be a reference to _somefunc, not result of _somefunc execution (_somefunc()).
As part of a xtype combo, I would like to know if the layer I choose in my simple data store (represented by this.getValue()) is present in the map layers. So if it does, A should occur, and B if it does not. The problem is that myLayer variable seems to be unrecognized, even though Opera Dragonify throws no error at all. Where would be the error?
listeners: {
'select': function(combo, record) {
for(var i = 0; i < mapPanel.map.length; i++) {
var myLayer = mapPanel.map.layers[i].name;
if (myLayer == this.getValue()) {
// do A here...
} else {
// do B here...
}
}
}
}
Thanks for any pointers,
I think the problem is that you are using this.getValue() instead of using combo.getValue().
I don't know how your app is set but it's usually a better idea to use the first parameter of your listener instead of the keywork this in order to avoid scope issues.
Hope this helps
#Guilherme Lopes Thanks for that, but the solution was this: mapPanel.map.layers.length instead of mapPanel.map.length.