Skip to content

Commit

Permalink
feat(view-strategy): enable exported view strategy and registry to be…
Browse files Browse the repository at this point in the history
… used for view models

Now, by using the module system to re-export a view strategy instance
or a view registry instance, the templating engine will be able to
discover that and use it as the source of the view for all the view
models contained in the module.

Fixes #13
  • Loading branch information
EisenbergEffect committed Mar 19, 2015
1 parent a696025 commit 03790f8
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 13 deletions.
4 changes: 2 additions & 2 deletions src/custom-element.js
Expand Up @@ -42,7 +42,7 @@ export class CustomElement extends ResourceType {
load(container, target, viewStrategy, transientView){
var options;

viewStrategy = viewStrategy || ViewStrategy.getDefault(target);
viewStrategy = viewStrategy || this.viewStrategy || ViewStrategy.getDefault(target);
options = {
targetShadowDOM:this.targetShadowDOM,
beforeCompile:target.beforeCompile
Expand All @@ -56,7 +56,7 @@ export class CustomElement extends ResourceType {
if(!transientView){
this.viewFactory = viewFactory;
}

return viewFactory;
});
}
Expand Down
15 changes: 10 additions & 5 deletions src/module-analyzer.js
@@ -1,14 +1,15 @@
import {Metadata, ResourceType} from 'aurelia-metadata';
import {TemplateRegistryEntry} from 'aurelia-loader';
import {ValueConverter} from 'aurelia-binding';
import {CustomElement} from './custom-element';
import {AttachedBehavior} from './attached-behavior';
import {TemplateController} from './template-controller';
import {ViewStrategy} from './view-strategy';
import {ViewStrategy,TemplateRegistryViewStrategy} from './view-strategy';
import {hyphenate} from './util';

class ResourceModule {
constructor(){
this.id = '';
constructor(moduleId){
this.id = moduleId;
this.moduleInstance = null;
this.mainResource = null;
this.resources = null;
Expand All @@ -19,6 +20,7 @@ class ResourceModule {
analyze(container){
var current = this.mainResource,
resources = this.resources,
viewStrategy = this.viewStrategy,
i, ii, metadata;

if(this.isAnalyzed){
Expand All @@ -29,6 +31,7 @@ class ResourceModule {

if(current){
metadata = current.metadata;
metadata.viewStrategy = viewStrategy;

if('analyze' in metadata && !metadata.isAnalyzed){
metadata.isAnalyzed = true;
Expand All @@ -39,6 +42,7 @@ class ResourceModule {
for(i = 0, ii = resources.length; i < ii; ++i){
current = resources[i];
metadata = current.metadata;
metadata.viewStrategy = viewStrategy;

if('analyze' in metadata && !metadata.isAnalyzed){
metadata.isAnalyzed = true;
Expand Down Expand Up @@ -138,7 +142,7 @@ export class ModuleAnalyzer {
return resourceModule;
}

resourceModule = new ResourceModule();
resourceModule = new ResourceModule(moduleId);
this.cache[moduleId] = resourceModule;

if(typeof moduleInstance === 'function'){
Expand Down Expand Up @@ -167,6 +171,8 @@ export class ModuleAnalyzer {
}
} else if(exportedValue instanceof ViewStrategy){
viewStrategy = exportedValue;
} else if(exportedValue instanceof TemplateRegistryEntry){
viewStrategy = new TemplateRegistryViewStrategy(moduleId, exportedValue);
} else {
if(conventional = CustomElement.convention(key)){
if(!mainResource){
Expand Down Expand Up @@ -197,7 +203,6 @@ export class ModuleAnalyzer {
mainResource = new ResourceDescription(fallbackKey, fallbackValue, fallbackMetadata);
}

resourceModule.id = moduleId;
resourceModule.moduleInstance = moduleInstance;
resourceModule.mainResource = mainResource;
resourceModule.resources = resources;
Expand Down
14 changes: 11 additions & 3 deletions src/view-engine.js
@@ -1,13 +1,21 @@
import * as LogManager from 'aurelia-logging';
import {Origin} from 'aurelia-metadata';
import {Loader} from 'aurelia-loader';
import {Loader,TemplateRegistryEntry} from 'aurelia-loader';
import {Container} from 'aurelia-dependency-injection';
import {ViewCompiler} from './view-compiler';
import {ResourceRegistry, ViewResources} from './resource-registry';
import {ModuleAnalyzer} from './module-analyzer';

var logger = LogManager.getLogger('templating');

function ensureRegistryEntry(loader, urlOrRegistryEntry){
if(urlOrRegistryEntry instanceof TemplateRegistryEntry){
return Promise.resolve(urlOrRegistryEntry);
}

return loader.loadTemplate(urlOrRegistryEntry);
}

export class ViewEngine {
static inject() { return [Loader, Container, ViewCompiler, ModuleAnalyzer, ResourceRegistry]; }
constructor(loader, container, viewCompiler, moduleAnalyzer, appResources){
Expand All @@ -18,8 +26,8 @@ export class ViewEngine {
this.appResources = appResources;
}

loadViewFactory(url, compileOptions, associatedModuleId){
return this.loader.loadTemplate(url).then(viewRegistryEntry => {
loadViewFactory(urlOrRegistryEntry, compileOptions, associatedModuleId){
return ensureRegistryEntry(this.loader, urlOrRegistryEntry).then(viewRegistryEntry => {
if(viewRegistryEntry.isReady){
return viewRegistryEntry.factory;
}
Expand Down
21 changes: 18 additions & 3 deletions src/view-strategy.js
Expand Up @@ -3,7 +3,7 @@ import {relativeToFile} from 'aurelia-path';

export class ViewStrategy {
makeRelativeTo(baseUrl){}

loadViewFactory(viewEngine, options){
throw new Error('A ViewStrategy must implement loadViewFactory(viewEngine, options).');
}
Expand All @@ -29,7 +29,7 @@ export class ViewStrategy {

annotation = Origin.get(target);
strategy = Metadata.on(target).first(ViewStrategy);

if(!strategy){
if(!annotation){
throw new Error('Cannot determinte default view strategy for object.', target);
Expand Down Expand Up @@ -81,4 +81,19 @@ export class NoView extends ViewStrategy {
loadViewFactory(){
return Promise.resolve(null);
}
}
}

export class TemplateRegistryViewStrategy extends ViewStrategy {
constructor(moduleId, registryEntry){
this.moduleId = moduleId;
this.registryEntry = registryEntry;
}

loadViewFactory(viewEngine, options){
if(this.registryEntry.isReady){
return Promise.resolve(this.registryEntry.factory);
}

return viewEngine.loadViewFactory(this.registryEntry, options, this.moduleId);
}
}

0 comments on commit 03790f8

Please sign in to comment.