Is there any way of telling exactly which attributes were changed on a dirty record using ember-data?
The docs show a changedAttributes method, but I can’t use that directly because I want to bind it in a template.
I could set up observers for every field to get an event when they are updated, but that seems like a tedious solution, I was wondering if there was an easier way.
Edit: My use case is basically that I'm trying to indicate which fields were modified in an "edit" form.
There is an object _attributes on the record that has all the modified properties/values, you could use Em.keys on it for them all.
Related
I have a field that I want to check if it's unique in my store. There are tons of tutorial on how to do this, but for my particular uniqueness it depends on the value of another value in the form. I need to check if the combined value is unique. Anyone have an idea on how to do this? The only solution I can think of is using a computed property (two fields combined), and having a validator on that. That seems kind of messy though.
I was able to get around this by adding the other field as an option.
This topic har been discussed on stackoverflow before, but not with latest version of ember data, I think. At least none of the suggestions I have found have worked for me.
I use the latest version of Ember and Ember data (versjon 2.13.0). I use the JsonApiAdapter.
Scenario
After I load a record from the server I want to do a few changes to some of its properties. These changes shall not make the record dirty, and the changed attributes shall not show up in the record.changedAttributes(). Any changes the user may do after that shall make the record dirty.
Searching for a solution
I have tried to manually change the isDirty flag, but it didn't do it. I have also tried to find the place in the ember data code that sets the state after a record has been loaded (because essentially I am trying to do the same thing) but I haven't found where it is.
I have also tried record.send('pushedData'), but I didn't change anything of the state of the record.
Any help appreciated.
I know 3 methods which allow to modify server's response without dirtying records:
You can override adapter's handleResponse method and make modifications right in payload.
You can override serializer's normalize method.
You can load records from server with Ember.$.ajax method, modify response and then pass it to store's pushPayload method.
First two methods are good if you need to modify record after every load from server (no matter from what route/controller you do it). Both adapter and serializer can be model-specific. If you need to do it in only one place (controller or route), or if you need an access to route's/controller's variables - 3rd method is good.
I'm not aware about any way to mark record as dirty/not dirty. If you modify a record after it was stored, it becomes dirty.
I'm using a DS.attr() data type in one of my Ember-Data models (note, no attribute type specified) to allow me to store nested JSON data. For the most part, it works fine, however, when I make changes (e.g. with an input bound to one of its properties) the record isn't marked as 'modified' in the Ember inspector, although the view bindings are all working properly (i.e. if I echo the same property as text, it changes when the input changes). Similarly, after making a change to one of these properties, if I call the rollback() function on the model, the data isn't rolled back.
Of course, the regular properties work just fine, so I'm assuming this has something to do with the DS.attr() type not being specified.
Is there a way to make this work efficiently? I would try to use embedded records, but this data doesn't use any record IDs.
Thanks
To answer my own question, the best solution I've been able to come up with is to use the ember-data.model-fragments addon. It's pretty slick, and solves both problems that I listed above.
Supposed I have a model containing 2 pre-populated fields. I would like to display these fields in the DOM for the user to modify if necessary. If I bind the DOM to the model using: {{input value=field1}} and {{input value=field2}}, then every time the user types in a character in one of these fields, Ember updates the bound model immediately. This is not the behavior I want. I prefer to show a button; when pressed, I want to validate data in the two fields in relation to each other, and if valid, update the model.
I considered creating mirrored fields in the controller and binding these to the DOM. Then create an action associated with the button to do the validation, and if data is found to be valid, copy data from the controller fields to the respective model fields. This technique may work, but seems like a very round-about way of doing something conceptually simple.
Do one of you Ember gurus out there have an opinion on how best to do this? I'm looking for best practices; please help.
I am not a guru nor am I familiar with client side validation in EmberData since our app uses server side validation.
Are you sure you can't allow your model to be updated immediately (i.e. bound to the template fields)?
If you did bind the model, then you could validate upon submission. If validation fails, you can just rollback the changes. If it passes, you can save the record. This is probably what I would do.
However, you clearly state that you do not want your model updated immediately, which means you don't want to bind your model.
Also, you have to do some processing that depends on multiple fields to validate, so it really sounds like binding to the controller and having a validation action is a good solution and that's what I would do if I wasn't binding to the model.
I am listing products as table rows, each row contains input fields for specifying the quantity of products.
I made a Fiddle for it here, http://jsfiddle.net/kroofy/4jTa8/19/
As you can see, after the input in the Qty field have been made, the whole row render again. And because of that the focus of the input field will be lost, which is not good if you want to input more than just one digit, or tab between input fields.
What would be the most elegant way to solve this?
I would handle this by setting model.set({qty: _qty}, {silent: true}) and then updating the non-input fields with this.$.
As an alternative to the silent treatment: rather than listening for change events, listen for change:qty and change:sellPrice and have a method that updates just the HTML that needs updating within this.$, rather than re-rendering the DOM object and breaking your focus.
Either way, your comment about "selective updating" on the fiddle is certainly the right way to go.
(this.$ is a backbone hack to jQuery that restricts all selectors to search only within the DOM of the View's element. The element doesn't even need an ID or class; it just needs to exist and the View maintains a handle to it. It's incredibly useful.)
i built a plugin for backbone called Backbone.ModelBinding that may be able to help in this situation. my plugin allows you to update portions of a view with data from a model, when the model changes.
i've forked / updated your fiddle to show it in action: http://jsfiddle.net/derickbailey/FEcyF/6/
i removed the binding to the model change. i've also added id attributes to the inputs of the form to facilitate the plugin (the attribute that the plugin uses is configurable, though). and lastly, i've added a data-bind attribute to the sell price total td.
you can get the plugin here: http://github.com/derickbailey/backbone.modelbinding/
hope that helps
FWIW: my plugin is an automated version of what Elf is suggesting. I've written code exactly like he is describing, numerous times, which is where the plugin came from. I just got tired of writing that code by hand :)