Created
April 13, 2015 23:57
-
-
Save axefrog/ba892af4e281e6c70c4a to your computer and use it in GitHub Desktop.
Aurelia self-referencing view causing stack overflow error
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<require from="./linked-data"></require> | |
<table> | |
<tbody> | |
<tr repeat.for="pair of pairs()"> | |
<td>${pair.predicate}</td> | |
<td> | |
<linked-data subject.bind="this" predicate.bind="pair.predicate" value.bind="pair.value"></linked-data> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The subset of functionality for dynamically composing a child view is adapted from Aurelia's | |
// compose element: https://github.com/aurelia/templating-resources/blob/master/src/compose.js | |
import { | |
LogManager, Container, CompositionEngine, ViewSlot, ViewResources, ConventionalViewStrategy, NoViewStrategy, | |
bindable, inject, noView, skipContentProcessing | |
} from 'aurelia-framework'; | |
import ExtensionRegistry from '../extension-registry'; | |
import ResourceManager from '../resource-manager'; | |
@noView | |
@skipContentProcessing | |
@bindable('subject') | |
@bindable('predicate') | |
@bindable('value') | |
@inject(ExtensionRegistry, ResourceManager, Element, Container, CompositionEngine, ViewSlot, ViewResources) | |
export class LinkedDataCustomElement | |
{ | |
constructor(extensions, resourceManager, element, container, compositionEngine, viewSlot, viewResources) { | |
this.log = LogManager.getLogger('LinkedData View'); | |
this.log.debug('Constructed'); | |
this.extensions = extensions; | |
this.resourceManager = resourceManager; | |
this.element = element; | |
this.container = container; | |
this.compositionEngine = compositionEngine; | |
this.viewSlot = viewSlot; | |
this.viewResources = viewResources; | |
} | |
present() { | |
this.useDefaultView = false; | |
var renderer = null; | |
if(this.predicate) { | |
renderer = this.extensions.get(this.predicate); | |
} | |
else if(this.value && typeof this.value === 'object') { | |
if(this.value['@id']) { | |
renderer = this.extensions.get(this.value['@id']); | |
} | |
else if(this.value['@type']) { | |
renderer = this.extensions.get(this.value['@type']); | |
} | |
if(!renderer) { | |
this.useDefaultView = true; | |
return; | |
} | |
} | |
if(!renderer) { | |
return; | |
} | |
var renderFunc = null; | |
switch(typeof renderer) { | |
case 'string': | |
processInstruction(this, { viewModel: renderer, model: this.value }); | |
return; | |
case 'function': | |
renderFunc = renderer; | |
break; | |
case 'object': | |
if(renderer.render) { | |
var self = this; | |
renderFunc = function() { | |
return renderer.render.apply(renderer, Array.prototype.slice.call(arguments)); | |
}; | |
} | |
break; | |
} | |
if(!renderFunc) { | |
return; | |
} | |
while(this.element.lastChild) { | |
this.element.removeChild(this.element.lastChild); | |
} | |
var result = renderFunc(this.value, this.element); | |
if(!result) { | |
return; | |
} | |
switch(typeof result) { | |
case 'undefined': | |
return; | |
case 'string': | |
this.element.innerText = result; | |
break; | |
case 'object': | |
if(result instanceof Element) { | |
this.element.appendChild(result); | |
} | |
else { | |
this.element.innerText = result.toString(); | |
} | |
break; | |
} | |
} | |
activate(value) { | |
this.value = value; | |
} | |
bind(executionContext) { | |
this.executionContext = executionContext; | |
if(this.value) { | |
this.present(); | |
} | |
} | |
valueChanged(oldValue, newValue) { | |
this.present(); | |
} | |
pairs() { | |
return Object.keys(this.value) | |
.map(key => ({ | |
predicate: key, | |
value: this.value[key] | |
})); | |
} | |
getViewStrategy() { | |
console.log('cdscsdcsd') | |
return this.useDefaultView ? null : new NoViewStrategy(); | |
} | |
} | |
function processInstruction(composer, instruction){ | |
return composer.compositionEngine.compose(Object.assign(instruction, { | |
executionContext:composer.executionContext, | |
container:composer.container, | |
viewSlot:composer.viewSlot, | |
viewResources:composer.viewResources, | |
currentBehavior:composer.currentBehavior | |
})).then(next => { | |
composer.currentBehavior = next; | |
composer.currentViewModel = next ? next.executionContext : null; | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment