Closed RomkeVdMeulen closed 8 years ago
There is, if you have the latest. We recently added a way to extend the binding context using view engine hooks. Here's an example that shows how to add an array of countries.
import {viewEngineHooks} from './view-engine-hooks';
let countries = [
...list of contries...
];
@viewEngineHooks()
export class CountryBinder {
beforeBind(view) {
view.overrideContext.countries = countries;
}
}
This plugs into the beforeBind hook and adds the countries to the overrideContext of the view that this data is required into. To make this work, you also need to implement a resource decorator:
import {resource} from 'aurelia-framework';
export function viewEngineHooks() {
return resource({
initialize(container, target) {
this.target = target;
},
load() {},
register(registry, name) {
registry.registerViewEngineHooks(new this.target());
}
});
}
We will have the viewEngineHooks decorator in the framework itself in a future release. For now, you can just add it to your project. Once this is in place, to use the countries, you simply require the countries module in your view:
<template>
<require from="./data/countries"></require>
<ul>
<li repeat.for="country of countries">${country}</li>
</ul>
</template>
For your scenario, you might want to create a single module that simply adds all your enums onto the overrideContext.
Rather than creating our own decorator, is it possible to register ViewEngineHooks with a naming convention?
export class EnumViewEngineHooks {
beforeBind(view) {
view.overrideContext.countries = countries;
}
}
Not currently...but if you want to submit a PR for that, it seems like a reasonable addition :) Code would be added in the ModuleAnalyzer. You will see the other similar code there.
That's a good idea, I'll look into that now.
Edit: Just needed to require it in the view.
However, I couldn't get the above code to work. Code for reference. Anything seem wrong here?
export enum ConnectorDirection {
Input,
Output,
TwoWay
}
@viewEngineHooks()
export class ConnectorDirectionBinder {
beforeBind(view) {
view.overrideContext.ConnectorDirection = ConnectorDirection;
}
}
export function viewEngineHooks() {
return resource({
initialize(container, target) {
this.target = target;
},
load() { },
register(registry, name) {
registry.registerViewEngineHooks(new this.target());
}
});
}
My guess is that it has something to do with the way that TypeScript handles enums
Pending https://github.com/aurelia/binding/pull/423, you can now achieve this behavior using either of the following:
import { ViewEngineHooks } from 'aurelia-framework';
import { viewEngineHooks } from 'aurelia-binding';
// by convention
export class CountryViewEngineHooks implements ViewEngineHooks {
beforeBind(view) {
view.overrideContext.countries = countries;
}
}
// by decoration
@viewEngineHooks()
export class CountryBinder implements ViewEngineHooks {
beforeBind(view) {
view.overrideContext.countries = countries;
}
}
Sorry for the necrobump of a closed issue but in case somebody else sees this, you can simply expose the enum from your view model like this:
In your ViewModel:
import {ERRORS} from 'some/module';
// or...
export enum ERRORS {
INVALID
}
export class MyViewModel {
private ERRORS = ERRORS;
private error: ERRORS = ERRORS.INVALID;
// ...
}
In your template:
<template>
<p if.bind="error === ERRORS.INVALID">Invalid!</p>
<!--The OP had an error in his example. Comparison requires `==` or `===`-->
</template>
@larvanitis I tried this but couldn't get it to work and no errors are thrown.
I'm looking at using a TypeScript enum for error states, like this:
This compiles to something like:
I tried simply doing
<p if.bind="error = ERRORS.INVALID">Invalid!</p>
but of course the enum isn't automatically available in the binding. Is there something I can do to make the enum available for comparisons?