Вам нужно получить положение мыши относительно холста
. Для этого вам нужно знать положение X / Y холста на странице.
Это называется «смещением» холста, и вот как получить смещение. (Я использую jQuery, чтобы упростить кросс-браузерную совместимость, но если вы хотите использовать сырой javascript, то быстрый Google тоже получит это.)
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
Затем в обработчике мыши вы можете получим мышь X / Y следующим образом:
function handleMouseDown(e){
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
}
Вот иллюстрирующий код и скрипка, который показывает, как успешно отслеживать события мыши на холсте:
http: //jsfiddle.net/m1erickson/WB7Zu/
Move, press and release the mouse
Down
Move
Up
Out
Это звучит просто правильным мне. Исключения предпочтительны, поскольку они могут быть брошены до вершины уровня служб отовсюду в уровне служб, неважно, как глубоко вложенный в сервисной реализации метода это. Это содержит служебный код в чистоте, поскольку Вы знаете, что звонящий предъявитель будет всегда получать уведомление о проблеме.
не ловят Исключение
Однако , не ловят Исключение в предъявителе, я знаю его привлечение, потому что это сохраняет код короче, но необходимо поймать определенные исключения, чтобы не ловить исключения системного уровня.
План Простая Иерархия Исключения
, Если Вы собираетесь использовать исключения таким образом, необходимо разработать иерархию исключения для собственных классов исключений. В minumum создают класс ServiceLayerException и бросают один из них в Ваших сервисных методах, когда проблема происходит. Тогда, если необходимо выдать исключение, которое должно быть обработано по-другому предъявителем, можно бросить определенный подкласс ServiceLayerException: скажите, AccountAlreadyExistsException.
у Вашего предъявителя тогда есть опция выполнения
try {
// call service etc.
// handle success to view
}
catch (AccountAlreadyExistsException) {
// set the message and some other unique data in the view
}
catch (ServiceLayerException) {
// set the message in the view
}
// system exceptions, and unrecoverable exceptions are allowed to bubble
// up the call stack so a general error can be shown to the user, rather
// than showing the form again.
Используя наследование в Ваших собственных средствах классов исключений, что Вы не обязаны ловить исключения мультигруды в своем предъявителе - Вы можете, если существует потребность к - и Вы не заканчиваете тем случайно, что ловили исключения, которые Вы не можете обработать. Если Ваш предъявитель уже во главе стека вызовов, добавьте выгоду (Исключение) блок для обработки системных ошибок с другим представлением.
я всегда пытаюсь думать о своем уровне служб как отдельная распространяемая библиотека и броске столь определенное исключение, как имеет смысл. Это тогда до presenter/controller/remote-service реализации, чтобы решить, должно ли это волноваться об определенных деталях или только рассматривать проблемы как универсальную ошибку.
Как Cheekysoft предполагает, я был бы склонен перемещать все основные исключения в ExceptionHandler и позволять тем исключениям пузырь. ExceptionHandler представил бы соответствующее представление для типа исключения.
Любые исключения проверки правильности однако должны быть обработаны в представлении, но обычно эта логика характерна для многих частей Вашего приложения. Таким образом, мне нравится иметь помощника как это
public static class Try {
public static List<string> This( Action action ) {
var errors = new List<string>();
try {
action();
}
catch ( SpecificException e ) {
errors.Add( "Something went 'orribly wrong" );
}
catch ( ... )
// ...
return errors;
}
}
Тогда, когда вызов Вашего сервиса просто делает следующий
var errors = Try.This( () => {
// call your service here
tasks.CreateMember( ... );
} );
Тогда по ошибкам пуст, Вы хороши для движения.
можно взять это далее и расширить его с помощью custome обработчиков исключений, которые обрабатывают редкий исключения.
В ответ на последующий вопрос:
Что касается создания исключений, становящихся утомительными, Вы отчасти привыкаете к нему. Использование хорошего генератора кода или шаблона может создать класс исключений с минимальным редактированием руки в течение приблизительно 5 или 10 секунд.
Однако во многих приложениях реального мира, обработка ошибок может составить 70% работы, таким образом, это - все просто часть игры действительно.
, Поскольку tgmdbm предлагает в приложениях MVC/MVP, я позволяю всему своему unhandlable пузырю исключений до вершины и пойман диспетчером, который делегирует к ExceptionHandler. Я настроил его так, чтобы это использовало ExceptionResolver, который смотрит в файле конфигурации для выбора соответствующего представления, чтобы показать пользователю. Библиотека Spring MVC Java делает это очень хорошо. Вот отрывок из файла конфигурации для преобразователя Исключения MVC's Spring - для Java/Spring, но Вы получите идею.
Это берет огромный объем обработки исключений из Ваших предъявителей/контроллеров в целом.
<bean id="exceptionResolver"
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="UserNotFoundException">
rescues/UserNotFound
</prop>
<prop key="HibernateJdbcException">
rescues/databaseProblem
</prop>
<prop key="java.net.ConnectException">
rescues/networkTimeout
</prop>
<prop key="ValidationException">
rescues/validationError
</prop>
<prop key="EnvironmentNotConfiguredException">
rescues/environmentNotConfigured
</prop>
<prop key="MessageRejectedPleaseRetryException">
rescues/messageRejected
</prop>
</props>
</property>
<property name="defaultErrorView" value="rescues/general" />
</bean>