In terms of data-binding, both elements are bound to the same binding context. Consider this example:
<div foo.bind="bar">
<div foo.bind="bar"></div>
</div>
You would expect both <div>
elements to have the same binding context right? Both element's foo
property should be bound to the same model's bar
property. The same holds true in this scenario:
<myelem foo.bind="bar">
<myelem foo.bind="bar"></myelem>
</myelem>
Both instances of <myelem>
are bound to the same binding context / model.
If I understand the question correctly, you would like an elegant way to give the inner MyElem class instance a reference to the outer MyElem class instance. Luckily, you're using Aurelia so there is a very nice way to do this... declare it as a dependency using the inject
decorator:
import {inject, Parent} from 'aurelia-dependency-injection';
import {customElement} from 'aurelia-framework';
@customElement("myelem")
@inject(Parent.of(MyElem))
export class MyElem {
constructor(parent) {
this.parent = parent;
}
...
}
There's one caveat however...
The Aurelia dependency-injection container's default behavior is to create an instance of the requested item if an instance is not found in the container. This means that @inject(Parent.of(MyElem))
is not quite what we want. In situations where there is no parent MyElem instance the container will create one for us instead of returning null. Normally we'd use @inject(Optional.of(MyElem))
to tell the container to give us the instance, only when it exists in the container. I don't know of a way to combine Parent.of and Optional.of. I'll create an issue in the aurelia dependency-injection repository so we can get this feature added.
In the meantime, we can easily create our own Resolver that combines the behavior of Parent.of and Optional.of:
import {resolver} from 'aurelia-dependency-injection';
@resolver()
export class OptionalParent {
constructor(key) {
this.key = key;
}
get(container) {
if (container.parent && container.parent.hasResolver(this.key, false)) {
return container.parent.get(this.key)
}
return null;
}
static of(key) {
return new OptionalParent(key);
}
}
So the new version of our MyElem class would look like this:
import {inject} from 'aurelia-dependency-injection';
import {customElement} from 'aurelia-framework';
import {OptionalParent} from './optional-parent';
@customElement("myelem")
@inject(OptionalParent.of(MyElem))
export class MyElem {
constructor(parent) {
this.parent = parent;
}
...
}
Here's a working example. Check the console for log messages showing the result:
https://gist.run/?id=1a84e0a466fb928aa075