Is there a way to get all bindings of all fields or checkboxes of a template in ember ?
The intention is to get them in a generic way, to store them in a generic way in a json object and to send them to the server. The server maps the variable names to the model attributes. Something like I call a function from the controller with the template name and get back all bindings ?
get_bindings("templatename":"test_template")
How should this method look like ?
This is really the purpose of two-way bindings in Ember. When you have an object that looks like...
person = Ember.Object.create({
name: 'Jane',
age: 25
});
and a template that looks like...
<div>Enter your name here: {{input value=person.name}}</div>
<div>Enter your age here: {{input value=person.age}}</div>
...then when you type something new in the boxes, your person object automatically gets updated. To persist your person, all you have to do is serialize the person object and send it off to the server. There's no asking the template for the new values or manually synchronizing the two.
If you are looking for a more sophisticated way of managing local model lifecycle and interacting with a server that follows certain JSON conventions, check out Ember Data or any of the other maturing data persistence libraries that are popping up.
Ember doesn't give you a way to easily interact with the view from the controller by design.
Related
I am new to ember and am trying to migrate an existing application, and would like to know what the recommendation is for modeling a single object that will be reused in multiple components on every page. ie: As part of the initial load, I would like to perform a GET request against a URL like 'https://example.com/currentUser' and get an object back like:
{
name: "Users Name"
email: "user#email.com",
profileImg: "http://example.com/pictureOfUser.png"
... snip ...
}
This object will then be used in components for menus, toolbars, and a form for updating it via a post to the same URL.
What is the best way to model this workflow in ember? Given that this is an incidental object and not the focus of most routes, it does not seem to make sense to specify it as the model of them. Also, does ember data handle cases where a model is a singleton and does not have an ID, or would I need to use something like Ember.$.ajax ?
What do you mean by "where a model is a singleton"?
If you use the ember-data default adapter, then yes, a model needs to have an ID, it's part of the JSONAPI spec. If you already have a backend with different conventions, take a look at extending or swapping out the default adapter.
A service is a singleton, and there is nothing preventing you from making an AJAX call there. You would be losing out on all the nice things that come along with ember-data, but, you can do it.
Say suppose I have a people's template (people.hbs), and I want to list all the people that is retrieved from a GET to http://backendserver/api/people.
However in future I decided to implement something that requires me to sort these people based on the data that I get from http://backendserver/api/vehicle_people. In this data there is only the people id and the vehicle id so I can't just connect people and its associated vehicle information together , I also get vehicle data from http://backendserver/api/vehicles.
Some of the confusion on how to implement this in Ember2 is
Should I put all this info inside routers/people.js
something like this
export default Ember.Route.extend({
model(){
return Ember.RSVP.hash({
people_with_vehicle: //find from this.store all the people and the vehicle ,
people_with_no_vehicle:,
all people:
})
}
How should I load the data for http://backendserver/api/vehicle_people if I don't want to create any specific route or template ?. In ember2 it does like an automatic load based on the route you go to e.g if you defined in your /adapters/application.js
export default DS.RESTAdapter.extend({
namespace: 'api',
host:'http://backendserver/'
});
Your "vehicle_people" endpoint is best mapped to an Ember Data model called VehiclePeople, which would be:
DS.Model.extend({
person: DS.belongsTo('person'),
vehicle: DS.belongsTo('vehicle')
})
There are other approaches, but let us map, at the model level, which vehicles people drive. First we establish the relationship between people and your little two-attribute people-to-vehicle map called vehicle_people:
vehiclePeople: DS.hasMany('vehicle_people', { async: true })
This will send a network request, or network requests, to the vehicle_people endpoints, based on the person's ID, whenever this field is accessed. We'll see an alternative way to handle that in a minute.
Now a computed property serves to gives us a list of the actual vehicles.
vehicles: Ember.computed.mapBy('vehiclePeople', 'vehicle')
and
hasVehicle: Ember.computed.bool('vehicles.length', 0)
Creating lists of people with or without vehicles is not a matter of the model; it's pre-calculation that you almost certainly want to do in your controller:
Ember.Controller.extend({
peopleWithVehicles: Ember.computed.filterBy('model', 'hasVehicle')
and so on.
If you want to preload the vehicle_people relationships, so Ember Data does not attempt to go out and get them one at a time, the best way is to do that in the beforeModel hook:
...route
beforeModel() { return this.store.find('vehicle_people'); }
Is this the right way to normalize the model?
Having the little model-but-not-a-model which does nothing more than contains mapping from one model (people) to another (vehicles) is probably not the right way to organize your models and endpoints. You would be much, much better off simply include vehicles directly in person. What's the roadblock to doing that?
Your route is nothing to do with your model, in terms of naming convention, although you would probably often have them the same, and nest your routes to create your UI.
Ember does not do any magical matching of your route name to the api endpoint name. Ember Data does a little name magic to match the API endpoint to the model in the store.
1.
I assume these would all be people, and that they would have an attribute which defines whther they are vehicle people or non vehicle people. You can also include associated models in a single API endpoint, if it makes sense.
Include the model on the route that matches the template you wish to use that data on, regardless of what the route is called.
Is there a convenient way to inspect the raw model data being passed from external API to Ember js and Ember Data models?
Something like the Ruby .inspect method. Is there any debug tool like this in for Ember Data?
I want to make sure that I am properly mapping to the JSON when the data gets to my Ember models. But it would be handy to see the data structures before having to explicitly define the attributes in the model class on the Ember side.
I am wondering if there something roughly analogous to this pattern:
App.Somedata = DS.Model.extend({
raw: this.inspect
});
and then in my template I could just dump it to the view as a property that conveys the whole structure.
{{#each item in controller}}
{{item.raw}}
{{/each}}
This is not for production, but just for discovery purposes when trying to explore the implementation of an API and how it is served over the adapter.
There are two parts to debugging this, the first would be to inspect the JSON payload in your browser console. (In Chrome, check the Network tab).
To check the internal data being stored in an EmberData object there are actually two places that are used for internal housekeeping object.get('_data') and object.get('_reference').
In your case I think the data is what you are hoping for.
Your other options are to call object.toJSON() or object.serialize() to see what the representation that would be returned to the server in the current state.
We have a full desktop application based in QT C++ (mac & windows). We utilize webkit to serve up the UI based in HTML and Javascript. We also interact with the C++ via a javascript bridge. I'm doing quite the overhall and incorporating Ember.js as the MVC for a much more modular UI.
My question pertains to the best method for persistance. Should I stick with the Javascript objects we currently utilize, or transition to Ember Data for persistence, and read/write via a function in Ember Data(translation layer)?
Also we utilize webkit, but should I see about instead utilising Node.js rather than strait html/js?
I'd like to not do drastic changes, but I want to do this right. Any advice?
From the Ember side, there's no reason to use Ember Data, because Ember works fine without it. But Ember's infrastructure relies heavily on the API provided by Ember.Observable, which is available to all subclasses of Ember.Object. Similarly, JavaScript arrays will support more Ember features if you use Ember.Array and Ember.MutableArray, although this will happen automatically unless you disable Ember.EXTEND_PROTOTYPES.
So one very reasonable approach would be to port your existing model classes to Ember.Object. That would require, among other things, using get and set to access properties. If you do this, then your objects will be first class Ember citizens, and you'll have access to all the neat features of Ember, including automatic view updates and data bindings.
Here's what Ember.Object looks like, and how it integrates with the rest of Ember:
MyApp.Person = Ember.Object.extend({
firstName: null,
lastName: null,
init: function () {
// You can put more initialization code here.
},
// Compute fullName based on firstName and lastName.
// This will automatically propagate updates when
// firstName or lastName changes.
fullName: function () {
return this.get("firstName") + " " + this.get("lastName");
}.property("firstName", "lastName")
});
var person = MyApp.Person.create({ firstName: "Jane", lastName: "Doe" })
Then, in an Ember view, you could write something like:
<p>{{person.fullName}}</p>
…and the view would automatically updated whenever firstName or lastName changed. Similarly, you could edit firstName using the following code:
{{view Ember.TextField valueBinding="person.firstName"}}
In this example, changes to the text field will be automatically propagated back to the underlying object. (Though you can get clever and build a text field that only propagates changes when the user is done editing.)
If you need to pass property updates from Ember to QT, see the guide to building getters and setters with computed properties or use observers. A lot depends on exactly how you're exposing your C++ APIs via your JavaScript bridge. But as long as you can tie into Ember.Observable somehow, you'll have full access to all of Ember's features.
I'm writing a calendar application, which will need to display events by month.
While I'll need to create objects to represent the calendar months, I take it that these these CalenderMonth objects should NOT be 'models' (in Ember terminology), since the CalendarMonth objects won't persist to the server (whereas the Event objects will). Instead, the CalendarMonths will be 'objects', build with a CalendarMonth 'class', extending Ember.Object
So then, what sort of controller do I use as a proxy to the (frequently changing) CalendarMonth object? A (vanilla) controller? An ObjectController? An ArrayController?
ObjectController seems like the way to go, since it really is my intention for the the controller to act as proxy to a single object. I think I'm only thrown by the fact that in the corresponding route object, I'd be assigning the CalendarMonth object as the controller's MODEL. When, it's not a model, it's just an object.
Put another way, my question is:
Is it bad practice to assign an Ember object which is NOT a model to an ObjectController's 'model' property?
It is not bad practice to use a normal JS object as a controller's model/content. All that matters is how the view is going to render the model. If you're only going to display a single event at a time, or a single month for all events in that month, then the ObjectController is your best bet.
An ArrayController is used for when you want to loop round your model/content in the controller and display each item in the view. I don't think you should worry too much about what controller you should use, it will become pretty obvious which one you want as soon as you decide how to create your view.
When Ember talks about using a Model for your controller, you can use your own Ember Object if you wish and then reference it in the controller, but it doesn't matter if that is a natural JS object or Ember Object. A controller sees both just fine.