简体   繁体   中英

How to create new object and store the old in array each time when button clicked? OOP JavaScript

How to each time when click "Create New Poly" button, store last object in array and create a new clean object to draw new separated polyline on the map. I'd like to keep the functionality of the old polylines. Now it is not possible to clean the object. Simplified example presented bellow.

HTML:

<button onclick="create()">Create New Poly</button>
<div id="map" style="width: 500px; height: 400px;"></div>

JS:

var map;
var listener;

var polys = [],
    poly = {};

create = function() {
    poly = new Poly();

    if ( !! listener) google.maps.event.removeListener(listener);
    listener = google.maps.event.addListener(map, 'click', function(e) {
        poly.addPoint(e.latLng);
    });
}

function Poly() {
    this.markers = [];
    this.setMap(map);
    polys.push(this);
}
Poly.prototype = new google.maps.Polyline();

Poly.prototype.addPoint = function(p) {
    var m = poly.createMarker(p);
    poly.markers.push(m);
    poly.getPath().push(p);
}

Poly.prototype.createMarker = function(p) {
    var marker = new google.maps.Marker({
        position: p
    });
    marker.setMap(this.getMap());
    return marker;
}

$(function() {
    map = new google.maps.Map(document.getElementById('map'), {
        center: new google.maps.LatLng(48.864715, 10.546875),
        zoom: 4,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    });
});

Demo: JSFIDDLE

Even after doing what Ben Davis suggested http://jsfiddle.net/LxGmR/ it still exhibits the problem.

Which I think is due to all the Ploy objects sharing the same prototype: Poly.prototype = new google.maps.Polyline(); . I think the fix is that each new Ploy object needs its own prototype google.maps.Polyline instance.

Which after testing, I have found to be true: http://jsfiddle.net/uhZFE/

Then I looked up how to do this without the wrapper function, I used the method described in the SO answer https://stackoverflow.com/a/6519265/388787 ( http://javascript.crockford.com/prototypal.html was also helpful) and produced http://jsfiddle.net/YgSwF/ which is the following; it works as you requested:

var map;
var listener;

var polys = [];

create = function () {
  var poly = new Poly();

  if ( !! listener) google.maps.event.removeListener(listener);
  listener = google.maps.event.addListener(map, 'click', function (e) {
    poly.addPoint(e.latLng);
  });
  polys.push(poly);
}

function Poly() {
  google.maps.Polyline.call(this);
  this.markers = [];
  this.setMap(map);
}
Poly.prototype = Object.create(google.maps.Polyline.prototype);

Poly.prototype.addPoint = function (p) {
  var m = this.createMarker(p);
  this.markers.push(m);
  this.getPath().push(p);
}

Poly.prototype.createMarker = function (p) {
  var marker = new google.maps.Marker({
    position: p
  });
  marker.setMap(this.getMap());
  return marker;
}

$(function () {
  map = new google.maps.Map(document.getElementById('map'), {
    center: new google.maps.LatLng(48.864715, 10.546875),
    zoom: 4,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  });
});​

I believe your problem has to do with variable scope. You should declare poly inside the create() function. Also, I think it would make more sense to do the pushing of the created object into the array within the create() function to adhere to separation of concerns.

Also, in your addPoint() function, you're referring to the global poly variable when you should be using "this".

Updated code:

var map;
var listener;

var polys = [];

create = function() {
    var poly = new Poly();

    if ( !! listener) google.maps.event.removeListener(listener);
    listener = google.maps.event.addListener(map, 'click', function(e) {
        poly.addPoint(e.latLng);
    });
    polys.push(poly);
}

function Poly() {
    this.markers = [];
    this.setMap(map);
}
Poly.prototype = new google.maps.Polyline();

Poly.prototype.addPoint = function(p) {
    var m = this.createMarker(p);
    this.markers.push(m);
    this.getPath().push(p);
}

Poly.prototype.createMarker = function(p) {
    var marker = new google.maps.Marker({
        position: p
    });
    marker.setMap(this.getMap());
    return marker;
}

$(function() {
    map = new google.maps.Map(document.getElementById('map'), {
        center: new google.maps.LatLng(48.864715, 10.546875),
        zoom: 4,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    });
});​

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM