Closed muziejus closed 10 years ago
This was complex, but I solved it.
First, I have the Individual
create a locations
computed property (is there a cleaner way to do this? I couldn't figure out how to do with .mapBy
):
App.Individual = DS.Model.extend({
...
addresses: DS.hasMany('address', {async: true}),
locations: function(){
array = [];
this.get('addresses').forEach(function(item, index){
array.push({location: item.get('location')});
});
return array;
}.property('addresses.@each.location')
});
Next, I tell the map view to use a different controller:
App.IndividualMapView = App.MapView.extend({
controller: App.IndividualsAddressesController.create({
container: App.__container__}),
childLayers: [
App.TileLayer,
App.MarkerCollectionLayer
]
});
Next, I define that new controller that is an ArrayController
, and, hence, will work with a MarkerCollectionLayer
:
App.IndividualsAddressesController = Ember.ArrayController.extend({
needs: ['individualsShow'],
content: Ember.computed.alias("controllers.individualsShow.locations")
});
And it works. Single Individual
, with three markers corresponding to three different Address
es on the map!
A slightly cleaner way to write that computed property would be:
locations: function(){
return this.get('addresses').map(function(item){
return {location: item.get('location')};
});
}.property('addresses.@each.location')
I didn't have the time to fully analyse your problem, sorry, but I don't like that reference to App.__container__
.
Thanks for the tip with map()
. I'm not really familiar with enumerable syntax in JS.
As for App.__container__
, I don't like it either, but without it, I get a complaint about the needs
. The idea came from here:
because that was the error I was getting.
Thanks for helping @miguelcobain!
An even simpler way, I'm pretty sure (new syntax), is: locations: Ember.computed.mapBy('addresses', 'location')
Agreed that App.__container__
is not idiomatic. Couldn't you just have:
App.IndividualMapView = App.MapView.extend({...});
App.IndividualMapController = Ember.ArrayController.extend({
needs: ['individualsShow'],
content: Ember.computed.alias("controllers.individualsShow.locations")
});
? then mapView.controller would automatically map to the controller you want?
I think he wanted an array with objects with a location
property. That's why I didn't use mapBy
.
That way you get an array with all the location
properties, which may also be appropriate for this case. However it's different from the original code.
Thanks for this feedback! @miguelcobain is right that I was trying to match the examples given by @gabesmed as closely as possible, hence, [{location: LatLng object}...]
. But the property is also sending more than just the location, so it "really" looks like this:
locations: function(){
name = this.get('firstName') + " " + this.get('lastName');
return this.get('addresses').map(function(item){
return {location: item.get('location'), popupContent: name + "<br>" + item.get('street')};
});
}.property('addresses.@each.location', 'addresses.@each.street', 'firstName', 'lastName')
With @gabesmed's suggestion, I get an Uncaught TypeError
pointing to line 791 of ember-leaflet (inside _contentDidChange
). This is the code:
App.IndividualMapController = Ember.ArrayController.extend({
needs: ['individualsShow'],
content: Ember.computed.alias("controllers.individualsShow.locations")
});
App.IndividualMapView = App.MapView.extend({
// controller: App.IndividualMapController.create(),
// controller: App.IndividualsAddressesController.create({
// container: App.__container__}),
childLayers: [
App.TileLayer,
App.IndividualMarkerCollectionLayer
]
});
If I uncomment either of the controller:
properties, I get the "specifies 'needs', but does not have a container" error again.
@miguelcobain ha totally right, i didn't see that @muziejus got it. Yeah you don't want to manually create controllers..but i think you're on the right track! If we can help any more, maybe you could make a minimal jsfiddle for us to look at? Otherwise you've figured it out and that we could be helpful!
I tried to make a jsfiddle, but I couldn't get it to work, ha ha. I'll try again.
I think these are important things to look at, because the power of ember-leaflet will, imo, grow once its is more closely hooked into ember-data. My use case described here, I imagine, is not so bizarre as to require non-idiomatic controller creation. I wish, for example, that there were examples that took this into account in the documentation (though I know that's a WIP that I could theoretically be a part of, though I don't know if I have a good enough understanding to start documenting). But this is getting off topic. What I've got works for what I need (and I can even extrapolate it).
Hey, I've had a lot of fun trying to get
ember-leaflet
to work in this project I'm working on, but now I'm getting profoundly stumped and actively frustrated.So it seems to be the case that a
MarkerCollectionLayer
requires anArrayController
, whereas aMarkerLayer
works with anObjectController
. So I can have one map with a marker collection layer, attached toaddresses.index
that shows each marker associated with each instance of theAddress
model (via a computedlocation
property that returns alatLng
), and another map, with a marker layer, that shows the specific marker associated with a specific instance ofAddress
inaddresses.show
. So far, so good.However, I have another model,
Individual
, whichhasMany('address', {async:true})
. Inindividuals.show
, I can see a text rendering of the content of theAddress
objects via an{{each}}
, but I can't, for the life of me, figure out how to get those three (say)Address
markers to show up in theIndividualMapView
for anIndividual
. Conceptually, I know I need to be giving the layer an array oflocation
s, but if I can't even get aMarkerCollectionLayer
with just one item in it—defined inIndividualsShowController
—to show a solitary marker, then I think that there's no chance of my showing a bunch.So is my assumption correct, that collection layers "only" work with array controllers? And if it's wrong, how I do I get around it? I'm not very good at ember, etc., so apologies if the answer is very simple.
Thanks!
Here's what's not working:
Yet when I replace
App.MarkerCollectionLayer
withApp.MarkerLayer
inApp.InvididualMapView
, the marker does appear.