My code is:
class myclass observable.Observable
{
let label = "test";
navigatingTo(args: observable.EventData)
{
target.on( "name", this._callback );
}
_callback ( eventData )
{
console.log( this.label);
}
}
When I print out this.label in the callback - "this" object is not the object that I expect - which I think should be the myclass instance.
I've got a separate method for the callback because I'm also calling .off() later and need a reference to the method (as opposed to anonymous function)
You can pass a third argument when subscribing with on(). The third argument will be used as a context(this) for the callback. So probably you want to do:
target.on("name", this._callback, this);
Related
As the title, what is exactly the difference of these two defs in Groovy?
Maybe it's a documentation problem, I can't find anything...
A method declaration without static marks a method as an instance method. Whereas a declaration with static will make this method static - can be called without creating an instance of that class - see https://www.geeksforgeeks.org/static-methods-vs-instance-methods-java/
def in groovy defines a value as duck typed. The capabilities of the value are not determined by its type, they are checked at runtime. The question if you can call a method on that value is answered at runtime - see optional typing.
static def means that the method will return a duck typed value and can be called without having instance of the class.
Example:
Suppose you have these two classes:
class StaticMethodClass {
static def test(def aValue) {
if (aValue) {
return 1
}
return "0"
}
}
class InstanceMethodClass {
def test(def aValue) {
if (aValue) {
return 1
}
return "0"
}
}
You are allowed to call StaticMethodClass.test("1"), but you have to create an instance of InstanceMethodClass before you can call test - like new InstanceMethodClass().test(true).
i am starting to learn model driven forms in angular and when i was going through the documentation of the model driven forms i found this
component.ts
this.myForm= this.fb.group({
'contact':['',Validators.required]
});
now when i went to the definition of the validator class i found this
export declare class Validators {
...
static required(control: AbstractControl): ValidationErrors | null;
...
}
which explains required is a static method in the validator class and it requires a AbstractControl as a parameter. but why then i am allowed to use it without passing any parameter inside it.
The required method returns an error map with the 'required' property: {'required':true} if the value of control: AbstractControl is empty and null if its not.
.
From the angular source code: https://github.com/angular/angular/blob/6.1.9/packages/forms/src/validators.ts#L133-L154
static required(control: AbstractControl): ValidationErrors|null {
return isEmptyInputValue(control.value) ? {'required': true} : null;
}
.
The reason why you can pass Validators.required without parenthesis and parameters is because Typescript is a superset of Javascript, which can store functions as variables:
var Foo = function (control: AbstractControl)
{
return anyVal;
};
Is the same as:
Foo(control: AbstractControl): any
{
return anyVal;
};
So doing this is completely valid
var Bar = Foo;
And because a function is just a variable holding executable code, we can store the function in multiple variables or pass it as a parameter, which is what is done in the FormControl.
So basically, when you do
const control = new FormControl('', Validators.required);
You are not executing the required method, because a method is executed only when parenthesis and parameters are added. Instead, you are passing the Validator function itself.
I'm using a Supplier to instantiate a field thread safe while avoiding consecutive calls to the synchronized method.
class MyClass extends AbstractClassWithContext {
Supplier<Foo> fooGetter;
Foo foo;
public MyClass() {
this.fooGetter = this::initFoo;
}
Foo getFoo(){
return fooGetter.get();
}
synchonized Foo initFoo(){
if(Objects.isNull(this.foo)) {
this.foo = getContext().getFoo();
}
this.fooGetter = () -> this.foo;
return this.foo;
}
}
When I'm running my Unit Tests I want to make sure that initFoo() is called exactly once. Sadly verify(classUnderTest, times(1)).initFoo() does not register that initFoo is entered. I debugged this and calling getFoo() does in turn enter initFoo.
Any ideas?
I assume your test code looks something like this:
MyClass spiedOnObject = spy(new MyClass());
spiedOnObject.getFoo();
verify(spiedOnObject , times(1)).initFoo();
The problem is that this.fooGetter = this::initFoo; is called before you start spying on the object. At this point this refers to the real object, not to the spy. And that reference is captured when the method reference is created. Therefore the call cannot be registered.
What's the difference between using _.extend({}, Backbone.Events) and _.clone(Backbone.Events) for an event aggregator? I have seen them both used for this purpose:
http://backbonejs.org/#Events
http://lostechies.com/derickbailey/2011/07/19/references-routing-and-the-event-aggregator-coordinating-views-in-backbone-js/
There is absolutely no difference. The definition of underscore's clone method is:
_.clone = function(obj) {
if (!_.isObject(obj)) return obj;
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
};
So if the argument to _.clone is an object, the cloning is done via:
_.extend({}, obj);
Using the _.extend({}, Backbone.Events) syntax makes sense, when you also want to define other properties on the new object. Because extend accepts any amount of arguments, each of which will be extended into the first argument, it is common to define evented objects as follows:
//define an evented object
var foo = _.extend({}, Backbone.Events, {
bar: function() { /*...*/ }
});
If not, is there anything like this on the horizon?
This is the one feature of JavaScript, Ruby, and Perl that I can't live without. I know you can fake it with a hash member, but I want to be able to create (arbitrary) "first class" members from a parser.
Currently there's nothing that can set a field that doesn't yet exist. The mirror API can be used to set fields that already exist, and may eventually be extended to support defining new fields dynamically.
You can also use the "noSuchMethod" method on a class to intercept setter / getter, and store the received value in a map.
For example (I can't remember the syntax exactly...):
class Foo {
var _dynamicProperties = new Map<String,Object>();
noSuchMethod(String function_name, List args) {
if (args.length == 0 && function_name.startsWith("get:")) {
// Synthetic getter
var property = function_name.replaceFirst("get:", "");
if (_dynamicProperties.containsKey(property)) {
return _dynamicProperties[property];
}
}
else if (args.length == 1 && function_name.startsWith("set:")) {
// Synthetic setter
var property = function_name.replaceFirst("set:", "");
// If the property doesn't exist, it will only be added
_dynamicProperties[property] = args[0];
return _dynamicProperties[property];
}
super.noSuchMethod(function_name, args)
}
}
And then you can use this in your code as follows:
var foo = new Foo();
foo.bar = "Hello, World!";
print(foo.bar);
Of course, this can lead to typos that will not be checked by the type checker, e.g.:
foo.bar = "Hello";
foo.baz = "Hello, World!"; // Typo, meant to update foo.bar.
There are ways you have type-checker validation by using redirecting factory constructors and an implied interface, but then it starts to get complicated.
Side note: This is what JsonObject uses to convert a JSON map to a class type syntax.