SVG в Sproutcore, доступ к DOM-узлам с помощью Sproutcore, привязка sproutcore-событий к DOM
Я экспериментирую со Sproutcore и пытаюсь использовать SVG (стандартную векторную графику) в приложении sproutcore. Мне нужно уметь "рисовать" на каком-то холсте, отображать такие элементы, как линии, прямоугольники, изображения. У SVG есть все это. Моя идея заключалась в том, чтобы включить SVG-изображение с использованием StaticContentView:
svg: SC.StaticContentView.design({
classNames: ['my-static-content-view'],
content: "<svg version='1.1' width='970' height='219'> \
<image id='someimage' x='410.5' y='122' width='25' height='25' xlink:href='"+static_url('/resources/layout/someimage.png')+"'></image> \
</svg>",
tagName: 'section'
})
Пока это прекрасно работает, svg-изображение отображается внутри приложения, также загружается подизображение. Теперь моя проблема: я хочу иметь возможность манипулировать svg-образом во время выполнения, добавлять новые узлы и привязывать sproutcore-события к различным узлам. Например: когда щелкают некоторые изображения в codenippet, я хочу, чтобы событие было запущено. Я подумал, что могу связать события, используя
SC.Event.add(someelement, "click", someHandler);
Но мне нужно иметь доступ к svg-DOM-узлу, "someimage", чтобы привязать к нему событие. Я гуглил и пробовал jQuery, используя $('someimage'). Get(0) и многие другие методы, но, похоже, ничего не работает.
Кто-нибудь может дать мне подсказку о том, как получить доступ к элементу? Я, возможно, делаю это неправильно, используя StaticContentView в первую очередь? Могу ли я построить SVG как собственный элемент Sproutcore-Element или View, чтобы упростить задачу?
2 ответа
Ваше решение может работать, но не правильно. Вы должны использовать события мыши * для реализации изменений. По умолчанию SproutCore уже прикрепит все события к вашему представлению и проверит, внедрили ли вы в него функции событий, когда событие происходит.
Используя обработчики событий мыши *, вы можете обратиться к текущему представлению через CoreQuery, используя this.$, И обратиться к элементу svg element / canvas через jQuery-подобный метод.
Причина, по которой ваш метод неверен, состоит в том, что сейчас очень трудно передавать какие-либо изменения содержимого в остальную часть приложения без необходимости написания связующего кода, который является одним из основных элементов, которые SproutCore был написан для замены.
Некоторое время назад я написал сообщение в блоге, в котором описывается, как сделать собственный SC.View. Хотя это не совсем касается того, что вы хотите сделать, основы более или менее одинаковы.
https://mauritslamers.wordpress.com/2013/01/22/how-to-make-a-custom-view-in-sproutcore-html-style/
Редактировать: забыл ссылку на пост в блоге
На самом деле это было довольно легко, мне немного стыдно, что я открыл новую ветку для этого, потому что это обычно означает, что я полностью потерян.
Решение: Как упоминалось выше, легко связать события sproutcore с объектами во время выполнения (например, когда новые элементы DOM добавляются во время выполнения, чтобы они вызывали событие sproutcore), используя
SC.Event.add(elem, "click", someHandler);
Моя проблема заключалась в том, как получить доступ к DOM-элементу. Оказывается, обычная jQuery-функция $() работает и с представлениями. Мне просто нужно было вызвать его непосредственно в StaticContentView, плюс я забыл # (дух). Так что в моем примере выше можно получить элемент someimage-DOM с помощью следующего кода:
elem = svg.$('#someimage')[0];
Обратите внимание, что svg в приведенном выше коде - это StaticContentView, а не svg-HTML-элемент внутри StaticContentView. Я только что понял, что это может быть немного сложно отследить.
Таким образом, полный код, выполняемый где-то внутри вашего sproutcore-приложения "App" с mainPane, содержащим только StaticContentView "svg", выглядит следующим образом:
elem = App.mainPane.svg.$('#someimage')[0];
SC.Event.add(
elem,
"click",
function(){alert('clicked!');}
);
Надеюсь, что кто-то столкнется с теми же проблемами и сэкономит время, читая это.
И еще кое-что: когда svg-view не является самым верхним видом на вашей панели, может быть очень удобно использовать метод SC.outlet. Посмотрите здесь.