import {inject} from 'aurelia-dependency-injection'; import {BoundViewFactory, ViewSlot, customAttribute, templateController, ViewFactory} from 'aurelia-templating'; import {createOverrideContext} from 'aurelia-binding'; /** * Creates a binding context for decandant elements to bind to. */ @customAttribute('with') @templateController @inject(BoundViewFactory, ViewSlot) export class With { /**@internal*/ viewFactory: any; /**@internal*/ viewSlot: any; /**@internal*/ parentOverrideContext: any; /**@internal*/ view: any; value: any; /** * Creates an instance of With. * @param viewFactory The factory generating the view. * @param viewSlot The slot the view is injected in to. */ constructor(viewFactory: ViewFactory, viewSlot: ViewSlot) { this.viewFactory = viewFactory; this.viewSlot = viewSlot; this.parentOverrideContext = null; this.view = null; } /** * Binds the With with provided binding context and override context. * @param bindingContext The binding context. * @param overrideContext An override context for binding. */ bind(bindingContext, overrideContext) { this.parentOverrideContext = overrideContext; this.valueChanged(this.value); } /** * Invoked everytime the bound value changes. * @param newValue The new value. */ valueChanged(newValue) { let overrideContext = createOverrideContext(newValue, this.parentOverrideContext); let view = this.view; if (!view) { view = this.view = this.viewFactory.create(); view.bind(newValue, overrideContext); this.viewSlot.add(view); } else { view.bind(newValue, overrideContext); } } /** * Unbinds With */ unbind() { let view = this.view; this.parentOverrideContext = null; if (view) { view.unbind(); } } }