Reputation: 10397
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
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
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