J. Barca
J. Barca

Reputation: 555

HTMLBars render test

Currently I am building an ember.js component which has 2 modes, display and edit. When the component is in display mode, it inline renders the template string, which is a property of an associated model. When in edit mode, the component displays the template string in a content editable. I had to make the component re-initialize upon mode toggle by putting 2 instances of the component in a template if/else statement. The following code in my component enables this:

`import layoutDefault from '../templates/components/positionable-element-default'` 

.....

  layout:Em.computed(->
    if @.get('layoutComponent.displayMode') 
      Ember.HTMLBars.compile(@.get('regionModel.textContent')) 
    else
      layoutDefault
  )

My idea for solving render failing to strip out the { and } characters of the template string and then recompile after alerting the user of the error.

I tried putting the compile function in a try catch but nothing is caught , presumably because its not the compiling that is the problem but rather the rendering.

Upon some research, I found Why Ember.onerror() not capturing the Assertion Failed error.? but it looks like I will never be able to catch assertion errors in production. Therefore my question is: is possible to ascertain whether or not a template string will render properly or not ? Or is this kind of functionality outside the scope of ember's capabilities ? Pointers much appreciated :)

Upvotes: 0

Views: 49

Answers (1)

TameBadger
TameBadger

Reputation: 1590

I'm think you might be able to solve your problem by using the component helper to display a component dynamically, have a look at this post for a detailed explanation on how it works etc.

Here is how I recommend you try to solve your problem using the component helper:

// components/toggling-component.js
export default Ember.Component.extend({
  mode: 'display',
  modeComponent: Ember.computed('mode', function(){
    return this.get('mode') + '-mode'
  }),
  actions: {
    setMode(mode){
        this.set('mode', mode) 
    }
  }
})

// templates/components/toggling-component.hbs
Current Mode: {{mode}}<br/>
<button {{action 'setMode' 'display'}}>Toggle Display</button>|
<button {{action 'setMode' 'edit'}}>Toggle Edit</button> 
<hr/>
{{component modeComponent text=model.textContent}}

Now, by toggling that mode property, you can load whatever modes you'd like, where a mode will correspond to components like the following two:

// templates/components/display-mode.hbs
Display Mode Component: <br/>
{{text}}

// templates/components/edit-mode.hbs
Edit Mode Component: <br/>
{{textarea value=text cols="80" rows="6"}}

Here is a twiddle that demonstrates the complete solution.

Upvotes: 1

Related Questions