reptilicus
reptilicus

Reputation: 10397

Ember.js options for updating a view

I've been playing around with Ember.js, and was wondering what are the best practices for updating the DOM on a data change.

Specifically, I have dividers with open and close buttons in them for each instance of a model. I want the open button to disappear if the state of the model object is "open", and the close button to disappear if the state of the model is "closed".

As far as I can tell, there are a couple of options.

A) Directly change elements in the DOM with jQuery in the view that called by the controller

B) Setup an observer that will auto reload the template, and have if/else statements in the template where things should change based on the model parameters that got updated.

Is one of those preferred (or neither)? What would you guys do?

Upvotes: 0

Views: 608

Answers (2)

MilkyWayJoe
MilkyWayJoe

Reputation: 9092

Take a look into this fiddle which shows this implemented in the other view/tab. This sample is using a simple Em.Controller instead of a Em.CollectionController, but it does what you need.

I have 2 css classes:

.visible {visibility: visible}
.invisible {visibility: hidden}

The following view is using them on classNameBinding at the child view. And I'm binding the model to the parent view with contentBinding pointing to the model at the controller, then the child view has a property that observes the currentState property at the parent. When you click this child view, it will set the currentState to 'closed' and it will evaluate the IsVisible method again, which feeds the proper value to the classNameBinding.

App.OtherView = Em.View.extend({
    templateName: 'other',
    contentBinding: 'controller.content',
    currentStateBinding: 'controller.content.state',
    ButtonView: Ember.View.extend({
        tagName: 'a',
        click: function(e) {
            this.set('parentView.currentState', 'closed');
        },
        classNameBindings: 'IsVisible:btn visible:invisible',
        IsVisible: function() {
            return this.get('parentView.currentState') === 'open';
        }.property('parentView.currentState')    
    })        
});

Here's how the template is being set up

<script type="text/x-handlebars" data-template-name="other" >
    <h2>Other</h2>
    ID: {{content.id}}<br />
    Name: {{content.name}}<br />
    State: {{content.state}}<br />
    {{#view view.ButtonView }}
        Close
    {{/view}}            
</script>

Alternatively, I have this this sample (here's the source) that's very similar in the concept of how to use the .property to achieve this same functionality, but this is a little more complex and that's for a navbar menu. Check how I'm doing the App.NavigationView, you'll find a child view named NavigationItemView which I have a classNameBinding. What this does is check the value of a property in my controller and then on the view. That comparison returns true or false, and it will populate the class name based on the expression that calls the isActive function property, almost same as the first fiddle that I wrote based on your question.

Hope this helps.

Upvotes: 2

mavilein
mavilein

Reputation: 11668

i think you need to detail your question. This is my answer based on the current understanding of your question: From my point of view both options are not a good practice with EmberJS. As far as i learned until now, it is one of the strengths of EmberJS, that you do not have to worry about manually updating the DOM. All you need to do is updating your Model or Controller Objects and all changes will automatically be propagated to the DOM automagically.

Best regards,

Upvotes: 1

Related Questions