ember.jsember.js-view

Accessing model data in router when using a view


I am looking for a way to access model data in a route when using a view to display model attributes.

Example

Template

<h2>New post</h2>

<form {{action save model on="submit"}}>
    <label>Title</label>
    {{input type="text" value=title placeholder="title" id="title"}}

    <label>Text</label>
    {{view "tinymce" value=text }}

    <button>Post</button>
 </form>

View Template

<textarea id="tinymce">
</textarea>

View

export default Ember.View.extend({
    templateName: 'views/tinymce-textarea',

    didInsertElement: function() {
        tinymce.EditorManager.execCommand('mceRemoveEditor',true, 'tinymce');
        tinymce.EditorManager.execCommand('mceAddEditor',true, 'tinymce');
    }
});

Router

export default Ember.Route.extend({

    ....

    actions : {
        save : function(model) {
            if (!model.get('title').trim() || !model.get('text').trim()) {
                return;
            }

            model.save().then(this.onSuccessfulSave.bind(this), this.onFailedSave.bind(this));
        }
    }
});

Now, obviously this doesn't work, since model.text is never bound in the view, like it would be if I were to use the textarea template helper:

{{textarea value=text placeholder="text" id="text"}}

But this is just one of many (many) ways I have tried to get this to work, and I am at a complete loss as how one would access model attributes in the route when using a view. And it does seem like a pretty common usecase to me too.

I have failed to find information regarding this on SO or anywhere else, so if anyone is able to help me, thanks in advance! / AS.


Solution

  • So one of the main things that you're missing out is binding the view to the controller. This is actually really straight forward to do, but without it Ember doesn't know that it should propagate changes between the two. The first thing I would do is this:

     {{view "tinymce" valueBinding="text" }}
    

    This says that the views value will be binded to the controller's text value. Whenever view's value is updated, it will propogate to the controller and vice versa.

    The next item to take care of is actually binding the value in the view. All you need to do is tell the input to bind it's value to the view's value. This can be done like this

    {{textarea value="view.value" placeholder="text" id="text"}}
    

    Try this out, and you can use this jsbin that I created as an example:

    http://emberjs.jsbin.com/qanudu/26/

    If you have any other questions just let me know, but this should solve your issues!