Skip to content
This repository has been archived by the owner on Nov 30, 2018. It is now read-only.

ng-repeat in <ui-gmap-windows #823

Closed
wallstudios opened this issue Oct 28, 2014 · 32 comments
Closed

ng-repeat in <ui-gmap-windows #823

wallstudios opened this issue Oct 28, 2014 · 32 comments

Comments

@wallstudios
Copy link

Not sure if this is an issue or if it simply isn't possible.
I'm trying to do a ng-repeat inside of either a <ui-gmap-windows or <ui-gmap-window using a ng-repeat on the marker.

in neither one can I get them to render from the controller.

{{item}}

displays nothing

if I do

{{item}}

it renders 1 1 2 2

any thoughts?

thanks

@nmccready
Copy link
Contributor

It needs a separate controller inside it to ng-repeat around.

@nmccready
Copy link
Contributor

People have asked this before, search around. Also the button click examples are the same thing.

@wallstudios
Copy link
Author

maybe I'm not getting it.
I can load information from a controller using a unique controller within the windows but I can not get it to ng-repeat at all.
I've search through questions before but have not found a solution. thats why I asked.
thanks.

@dgriego
Copy link

dgriego commented Oct 29, 2014

@wallstudios, same here.. I've looked at past solutions with no concrete example or solution

@wallstudios
Copy link
Author

Perhaps it's a question more for an angularjs forum as I is most likely not specific to angular-google-maps.

@aesnyder
Copy link

Can you guys post your window markup?

So one of the things you'll notice is that you can't use ng-repeat, ng-show, ng-if or a handful of other helpers in the windows directive.

I believe the problem stems from the fact that in order to access model properties we need to use ng-non-bindable which in turn makes it impossible to use ng-repeat, ng-if, etc.

You can provide a controller to the infowindow which will make ng-repeat, ng-show, ng-if all work:
https://github.com/angular-ui/angular-google-maps/blob/master/example/example.html#L66-L71

The problem I'm finding is that when I do that, I can ng-repeat over items in the associated controller but not items that are stored on the property of the model.

Right now, I'm trying to figure out how to pass the scope correctly to the window so that we will be able to access model properties without ng-non-bindable.

Wish me luck.

@aesnyder
Copy link

@wallstudios @dgriego ^

@wallstudios
Copy link
Author

Luck....

I'm trying to find some time to put together a plunker.

I'll have a look at the example file and see if I can get it to do what I'm after.

@aesnyder
Copy link

Luck?

@wallstudios
Copy link
Author

@aesnyder you said to wish you luck. so I said luck..

how about good luck. is that better?

@aesnyder
Copy link

hah sorry I forgot I said that, too much code!

@nmccready
Copy link
Contributor

Also people should note that in order to have a window there is no requirement to use windows with markers. In-fact in most cases it is way more efficient to do the following.

<ui-gmap-markers models="some_models" blah blah></ui-gmap-markers>
<!-- one or many active windows -->
<ui-gmap-window ng-repeat="m in some_active_markers"> </ui-gmap-window>
<!-- one window at all times -->
<ui-gmap-window coords="active_window" > </ui-gmap-window>

@nmccready
Copy link
Contributor

If you use windows you are putting all the windows into the dom and memory at once. If you do as noted above you only do 1 - few .

@aesnyder
Copy link

will that give us the ability to use ng-if and ng-repeat on model attributes?

@wallstudios
Copy link
Author

ok.

Having a look at the example template. If I add into the map.markers2 section the following


                <div ng-controller='InfoController'>

                {{single}}

                <div ng-repeat="product in products">{{product.name}} </div>

                    <a class="btn" ng-click="clickedButtonInWindow()">CLICK ME</a>
                </div>

                <p ng-non-bindable >This is an info window at {{ latitude | number:4 }}, {{ longitude | number:4 }}!</p>

                <p class="muted">My marker will stay open when the window is popped up!</p>
            </div>
        </ui-gmap-windows>
    </ui-gmap-markers>

and adding this to the InfoController in info.js

    $scope.single = 'just once';

    $scope.products = [
       { id: 1, name: 'test', color: 'red' },
       { id: 2, name: 'bob', color: 'blue' }
    ];

i get the following out putted into the infowindow

just once
test
test
bob
bob

so while it will now render a ng-repeat it is done twice.

@wallstudios
Copy link
Author

Is there any way I can get a value of the marker that has been clicked with in the new controller 'InfoController'?

I can render using the ng-non-bindable but I want to be able to use it as either in a filter for the info that is displayed or pass it back to the 'InfoController'.

thanks.

@dgriego
Copy link

dgriego commented Oct 30, 2014

I have a slightly different setup, but the same outcome as @wallstudios:

    <ui-gmap-window coords="active_marker"
                    show="active_marker.showWindow"
                    options="active_marker.options"
                    closeClick="active_marker.closeClick">`

here I include the html for the window:

....
<div class="more-info" ng-controller="InfoController">
                <a class="website"
                   ng-repeat="a in lodging.websites"
                   ng-href="{{a.website_urll}}"
                   target="_blank">
                   ......
            </div>

The ng-repeat works, although it is duplicating each item 3 times just as @wallstudios described.
I've been looking around and I found this (http://stackoverflow.com/questions/20083220/ng-repeat-repeats-too-often) it may be of no help, but thought I should share.. meanwhile I'm looking for a solution as well.

@wallstudios
Copy link
Author

hay @dgriego how are you determining the 'active_marker' in your ng-repeat?

@dgriego
Copy link

dgriego commented Oct 30, 2014

@wallstudios, that was some interesting workings with a past issue @nmccready showed me, it is related to this PR: #83.. search for epiphany. I needed a way to show one info window at a time, so it was a variation of what is in the 'epiphany' discussion.

Basically I loop through all my markers like so:

_.each($scope.map.markers, function(marker) {
                marker.closeClick = function() {
                    marker.showWindow = false;
                };
                marker.onClicked = function() {
                    marker.showWindow = false;
                    onMarkerClicked(marker);
                };
            });

the onMarkerClicked function grabs the current marker object and creates a new scope for that window instance:

var onMarkerClicked = function(marker) {
            $scope.active_marker = marker;
            $scope.active_marker.showWindow = true;
            GoogleMapApi.then(function(maps) {
                $scope.active_marker.options = {
                    boxClass: 'custom-info-window',
                    pixelOffset: new maps.Size(-40, -362)
                };
            });
            $scope.$apply();
        };

note that the GoogleMapApi part was because I wanted to implement a custom info window and I had to use the new maps.Size because the info window was not positioned the way I wanted

@wallstudios
Copy link
Author

not sure if this will help or not but when I put a filter on the ng-repeat it stops returning two results.

    <div ng-repeat="product in products | filter:{ name: 'bob' }">{{product.name}} </div>

returns only bob

once

@wallstudios
Copy link
Author

ok not quite right. I added more items to the array and it returns the correct filtered item as many times as there is other items. so if 8 incorrect items it returns it 8 times etc

@aesnyder
Copy link

Lets not work around the problem, lets fix it.

Basically we don't want to have to use ng-non-bindable in the template in order to access model attributes. If we can get that, we don't need ng-non-bindable and all the ng-repeats and ng-ifs are just gonna work.

I believe that we need to do some work about here:

https://github.com/angular-ui/angular-google-maps/blob/master/src/coffee/directives/api/models/child/window-child-model.coffee#L148

My hope was that compiling the template with the current scope would get us access to {{model.attribute}} inside the template.

            unless @gWin.isOpen()
              @gWin.setContent $compile(@element)(@scope)[0]
              @gWin.open(@mapCtrl, if @getGmarker() then @getGmarker() else undefined)
              @model.show = @gWin.isOpen()

No luck so far... Any ideas @nmccready

@aesnyder
Copy link

I think part of the hiccup is in the use of transclusion for rendering the infowindow, though I'm not sure I have a firm understanding of how and why we're doing that.

@aesnyder
Copy link

@aesnyder
Copy link

@wallstudios @dgriego got it, tldr; use a templateUrl instead of rendering your content in the actual windows.

V 2.1 will only allow windows to render using templates.

@wallstudios
Copy link
Author

Sounds promising @aesnyder . Not going to have a chance to look at templates today as I need to get something off to a client. But I will once I can to see if I can get it to work.

@micheltl
Copy link

Hi Guys,

it's not clear for me. Does this issue closed ? It seems not but I'm not sure, so I prefer to ask the question...

I use angular-google-maps 2.0.12, and ng-repeat/ng-if/ng-show/ng-hide don't work in ui-gmap-window, even if I have another controller for the div :

`



blabla1



blabla2

`

I can see blabla1 blabla2 but no image between .

Anyone can give a help ? Thanks in advance.

@alexbonhomme
Copy link

Hi,

Actually I agree with you one this it's not clear. I will try to get this more clear.

If you want use ng-repeat and all you have to use the templateUrl and templateParameter attributes. No need to dedicated controller, as you can see on the following.

<ui-gmap-google-map center="map.center" zoom="map.zoom">
    <ui-gmap-window show="map.window.show" coords="map.window.model" options="map.window.options" closeClick="map.window.closeClick()" templateUrl="'views/modules/templates/infowindow.tpl.html'" templateParameter="map.window"></ui-gmap-window>
    <ui-gmap-markers idKey="'bid'" models="map.markers" coords="'self'" doCluster="false" fit="'true'" icon="'icon'" events="map.markersEvents" options="'options'"></ui-gmap-markers>
</ui-gmap-google-map>
$scope.map = {
    center: {
        latitude: 50.6278,
        longitude: 3.0583
    },
    zoom: 12,
    markers: [], // array of models to display
    markersEvents: {
        click: function(marker, eventName, model, arguments) {
            $scope.map.window.model = model;
            $scope.map.window.show = true;
        }
    },
    window: {
        marker: {},
        show: false,
        closeClick: function() {
            this.show = false;
        },
        options: {} // define when map is ready
    }
};

And finally the infowindow.tpl.html

<div class="gm-pro-popup">
    <header>
        <h3>{{parameter.model.title}}</h3>
    </header>
    <u>Users</u>
    <ul>
        <li ng-repeat="user in parameter.model.users">{{user.username}}</li>
    </ul>
</div>

Hope this is clearer for you! =)

@deveshsinghal22
Copy link

Thanks @BlckShrk , This works for me.

@amgadfahmi
Copy link

@BlckShrk thanks buddy, love the clean code 👍

@alexbonhomme
Copy link

Happy to help :)

@namelivia
Copy link

Commenting on @BlckShrk solution, that worked for me (thanks!). I had to pass map.window.model as the parameter and not just map.window, that is firing a cyclic oject value error for me.

@angular-ui angular-ui locked and limited conversation to collaborators Sep 14, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants