Смешивание пользовательских наложений Google Maps с просмотром магистралей - PullRequest
6 голосов
/ 02 февраля 2012

TL; DR

Является ли PinView.prototype = _.extend(PinView.prototype, google.maps.OverlayView.prototype) "правильным" способом наследования Backbone View от другого "класса"?

Длинное чтение

Мы переделываем наш сайт с использованием Backbone и работаем над включением некоторых функций отображения.

У меня есть представление Backbone, которое обрабатывает размещение <div> s в определенных точках в пределахокно браузера;Это кажется естественным для расширения, чтобы API Google Map поместил их в географические координаты.

В соответствии с Google API , для создания пользовательского наложения вы создаете новый объект.и установите прототип для этого объекта в новый экземпляр google.maps.OverlayView.Затем вы реализуете три функции поверх этого объекта, чтобы объект реагировал на:

onAdd

draw

onRemove

Где onAdd отвечает за генерацию HTML и его применение поверх Карты.Впоследствии это вызывает draw, который правильно позиционирует элемент в соответствии с указанными вами парами и границами LatLng.onRemove вызывается, когда вы хотите избавиться от своего слоя.

Поэтому я изменил свой вид, чтобы включить эти три метода (которые просто вызывают render и unrender и привязаны к моей коллекции).И затем, чтобы «волшебство произошло», я делаю:

PinView.prototype = _.extend(PinView.prototype, google.maps.OverlayView.prototype)

Это выглядит правильно?Я могу опубликовать код для представления и модели, на которых он основан, но, честно говоря, они не имеют отношения к этому примеру - код работает, и я могу разместить пользовательские div, сгенерированные с помощью модели, представления и модели Backbone.Компоненты контроллера на карте без проблем, что я спрашиваю, я думаю (и, возможно, этот вопрос более уместен для programmers.se, так что дайте мне знать, и я перенесу его).

Кажется, этобыть самым простым способом сделать мой PinView одновременно Backbone View и Google Maps OverlayView, но я не на 100% удобен с наследованием прототипов, чтобы знать, делаю ли я что-то «неправильно» или что-то сломаю в будущем.

Ответы [ 2 ]

2 голосов
/ 03 февраля 2012

Хорошая идея!Я обычно немного скептически отношусь к погоде или нет, вы «правы», когда все работает, так что, если вы не столкнулись с шоу-стоппером, и наложения появляются, и вы делаете то, что должны, я бы сказал,.

Одна вещь, которую стоит проверить поближе, хотя:

Это не (и не может быть) «реальное» множественное наследование - эта концепция на самом деле не актуальна в прототипеязык: одна реализация метода неизбежно "победит" и перезапишет другую реализацию, по крайней мере при использовании _.extend()

Это означает, что если в Backbone.View и * есть члены или методы с одинаковыми именами1009 * тот, кто последний в вашем _.extend() вызове, будет тем, кто вступит во владение.Но когда я осматривал их с помощью Chrome Developer Tools, я не видел никаких явных столкновений такого рода.

Поэтому моя рекомендация: продолжайте использовать это, просто много тестируйте.Я хотел бы увидеть пример этой техники когда-нибудь.

1 голос
/ 07 марта 2012

Ах! Так что я делал все вышеперечисленное, но это никогда не казалось правильным.

Затем я нашел это обсуждение группы Backbone , которое приводит меня к следующему:

var MyView = (function(){
    var view = function(){
        Backbone.View.apply(this, arguments);
    };

    view.extend = Backbone.View.extend;

    _.extend(view.prototype, Backbone.View.prototype, google.maps.OverlayView.prototype, [other prototypes...], { [VIEW DEFINITION] });

    return view;
}());

Таким образом, если нам нужно переопределить любое из определений в классе, из которого мы extend извлекаем данные, мы можем это сделать, так как он находится в цепочке _.extend раньше (более поздние определения перезаписывают более ранние определения).

Я работаю над «расширением» extend, чтобы отслеживать ссылки «родительского» объекта, которые будут переопределены, и предоставлять метод для их вызова (как в вызове Python super). Я не решил, следует ли это делать с помощью патчей для обезьян, паттерна перехватчика (с помощью метода _.tap() подчеркивания или чего-то еще, но я думаю, что это добавит большую гибкость.

Это позволит вам определить представление initialize в вашем "родительском" классе, которое можно вызвать, выполнив что-то вроде _.super('ParentClass', 'initialize'); в конце initialize подпрограммы "дочернего" класса ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...