Приветствую!
-- Прошу помощи сообщества в очередной раз. На сей раз заблудился в передаче данных между классами. Например есть Seaside приложение из нескольких компонентов - субклассов WAComponent (назову их Arender, Brender, Crender) и субкласса Object (Dcollection) с переменной collectionTasks, которая инициализируется OrderedCollection. Первоначально в приложении отображены Arender и Brender. В Brender выводится экземпляр Dcollection Затем из Arender вместо него вызывается Crender в котором реализована форма для добавления нового элемента в коллекцию Dcollection Вот здесь то и задумался... Ведь в Brender выводится экземпляр Dcollection и если в Crender создавать новый экземпляр Dcollection, то как их совместить? Пробовал создать метод класса Brender add:, но не могу правильно написать чтобы метод класса добавлял данные в переменную экземпляра (и вообще возможно ли так?) Вот собственно и вопрос. Можно ли как-то выстроить цепочку колбеков Arender -> Crender -> Brender без задействования методов и переменных на стороне класса? Или если для этого не иначе как использовать методы на стороне класса, то как правильно это реализовать? К сожалению в литературе это довольно туманно прописано, пробовал просто перенести рабочие методы и переменные экземпляра на сторону класса, но не это не взлетело... -- http://groups.google.ru/group/sugr --- Вы получили это сообщение, поскольку подписаны на группу Russian Smalltalk User Group. Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес [hidden email]. Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out. |
На стороне класса делать ничего точно не надо, потому что эти данные будут глобальными на образ, и о многопользовательском доступе к приложению можно будет забыть. Первоначально в приложении отображены Arender и Brender. В Brender выводится экземпляр Dcollection Как-то у вас всё запутанно. Рендеры всякие. Если задача Crender - форма добавления нового элемента, то зачем ему вообще знать о коллекции? Пусть возвращает в #answer: тот объект, который в этой форме заполняется, а уж вызыватель сам определит, что с ним делать (в вашем случае - ложить в коллекцию).
Дмитрий 24 сентября 2013 г., 21:08 пользователь Genosse Alex <[hidden email]> написал:
-- http://groups.google.ru/group/sugr --- Вы получили это сообщение, поскольку подписаны на группу Russian Smalltalk User Group. Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес [hidden email]. Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out. |
"render" - это просто для примера (как бы символизирует факт, что этот класс визуализируется Seaside, а так название может быть любое, не суть)
-- Дело в том, что из Arender вызывается Crender (в котором форма для редактирования экземпляра Dcollection), но Arender ничего не знает о Dcollection. О Dcollection знает Brender и #answer: от Crender к Arender, я так понимаю, пролетает мимо... вторник, 24 сентября 2013 г., 22:05:21 UTC+4 пользователь Dmitry Matveev написал:
-- http://groups.google.ru/group/sugr --- Вы получили это сообщение, поскольку подписаны на группу Russian Smalltalk User Group. Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес [hidden email]. Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out. |
--
-- http://groups.google.ru/group/sugr --- Вы получили это сообщение, поскольку подписаны на группу Russian Smalltalk User Group. Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес [hidden email]. Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out. |
Ещё попробовал финт ушами:
-- Создал в Arender экземпляр Dcollection с целью изменить его и породить от него, в свою очередь, экземпляр в Brender ... И тут осознал факт того, что я ни хрена не понял как работает call -> answer -> onAnswer... Перечитал seasidebook и всё равно не понял, то есть если делать как написано, то оно работает, но как работает непонятно и как использовать в отличных от примера ситуациях непонятно -- http://groups.google.ru/group/sugr --- Вы получили это сообщение, поскольку подписаны на группу Russian Smalltalk User Group. Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес [hidden email]. Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out. |
In reply to this post by Genosse
Я не понимаю… Проблема в том, что Brender после того, как был осуществлен возврат из Crender, не отображает изменения в Dcollection? Или Crender создает другой экземпляр и вы хотите ее "просунуть" в Brender?
-- -- Best regards, Dennis Schetinin 24 сентября 2013 г., 23:23 пользователь Genosse Alex <[hidden email]> написал:
-- http://groups.google.ru/group/sugr --- Вы получили это сообщение, поскольку подписаны на группу Russian Smalltalk User Group. Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес [hidden email]. Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out. |
Кажется я придумал как изменить содержимое коллекции в Brender опосредовано, но не могу проверить... На текущий момент, как мне кажется проблема, в том, что я не пойму как работать с call, answer, onAnswer. Т.е. с call всё понятно, он вызывает др. компонент, который временно замещает исходный. answer закрывает временно вызванный компанент и передаёт управление исходному компоненту, при этом в answer: может быть вложено некое полезное содержимое из временно вызванный компонента. НО в какое место исходного компонента попадает этот answer: с содержимым? Где в исходном компоненте прописывать действия на получение ответа? в том же методе которые вызывает временный компонент или где-то ещё? Как их прописывать? Почему в примерах в некоторых случаях используется onAnswer, а в некоторых вообще ничего, чем эти случаи отличаются? Никак не складываются из прочитанного целостная картина любые попытки сделать хоть что нибудь с применением answer отличное от конкретных примеров из книги, пока оканчиваются крахом. среда, 25 сентября 2013 г., 13:46:36 UTC+4 пользователь chaetal написал:
-- http://groups.google.ru/group/sugr --- Вы получили это сообщение, поскольку подписаны на группу Russian Smalltalk User Group. Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес [hidden email]. Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out. |
Есть метод call:, а есть метод call:onAnswer:. Также есть answer и answer:. В первом случае вам не важно получать информацию от вызываемого, во втором случае важно. Параметр в answer: попадет в onAnswer:.
-- Следуйте шаблону MVC. У вас должна быть ссылка на модель и вы просто обновляете модель на какой-либо сигнал. Изменение модели должно автоматически вызывать обновление вида. Я как-то баловался на Seaside, но не доделал. Вот ссылка http://citizentools.seasidehosting.st. Если нужно могу поделится кодом. среда, 25 сентября 2013 г., 13:14:31 UTC+3 пользователь Genosse Alex написал:
-- http://groups.google.ru/group/sugr --- Вы получили это сообщение, поскольку подписаны на группу Russian Smalltalk User Group. Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес [hidden email]. Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out. |
Ну а как этим пользоваться? Вот к примеру есть в книге один пример с этим onAnswer:Там конструкция некийМетод onAnswer:[...] Помещена в метод initialize пробую соорудить подобное получаю doesNotUnderstand: #onAnswer: Да и вообще почему он там в initialize? может в другом случае он должен быть в другом месте? Не пойму логику использования этого механизма Какие шаблоны есть для этой связки call:onAnswer: или просто answer:? На основании чего применяется один из них? среда, 25 сентября 2013 г., 14:44:35 UTC+4 пользователь kirand написал:
-- http://groups.google.ru/group/sugr --- Вы получили это сообщение, поскольку подписаны на группу Russian Smalltalk User Group. Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес [hidden email]. Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out. |
Вообще-то #call: возвращает то, что в вызываемом компоненте засунули в #answer. В этом, грубо говоря, вся суть продолжений. Иными словами
25 сентября 2013 г., 15:53 пользователь Genosse Alex <[hidden email]> написал:
-- http://groups.google.ru/group/sugr --- Вы получили это сообщение, поскольку подписаны на группу Russian Smalltalk User Group. Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес [hidden email]. Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out. |
In reply to this post by Genosse
Очевидно, onAnswer: позволяет назначить один обработчик на все вызовы подкомпоненты. Как я понимаю, если в лом писать в десяти местах одну и ту же обработку результата вызова (а по идее, и должно быть в лом), ю а, как говорится, уелкам! Элементарный гуглинг дает довольно много полезных результатов: http://www.seaside.st/documentation/subcomponents (с вызовом onAnswer: в initialize — а почему, собственно, и нет?) и даже такой: http://forum.world.st/The-onAnswer-message-what-does-it-do-td4690068.html — с откровением "My mistake! I didn't subclass `StTaskEditor' from `WAComponent'. " Надеюсь, поможет. Если нет, придется лезть в образ… :) -- Best regards, Dennis Schetinin 25 сентября 2013 г., 15:53 пользователь Genosse Alex <[hidden email]> написал:
-- http://groups.google.ru/group/sugr --- Вы получили это сообщение, поскольку подписаны на группу Russian Smalltalk User Group. Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес [hidden email]. Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out. |
Угу оба первых источника и штудировал, про них я, собственно, вопрос и задавал почему там в onAnswer: в initialize. А главное почему метод, который указан, перед onAnswer: понимает onAnswer:, а у меня нет И таки да у меня класс не являлся потомком WAComponent Мой класс из которого я вызываю другой компонент это полотно SVG-графики наследующее от SeasideDynamicSVG но в SeasideDynamicSVG-Core есть call: aComponent onAnswer: aBlock Так что вроде должно работать, но не работает... :( Всё таки я что-то не правильно пишу... Указанные источники информации уже не помогают. Я несколько дней читал прежде чем задал вопрос. Изучение Smalltalk чаще любого другого занятия заставляет меня усомниться в собственной полноценности... :) Могу ли я узнать как бы специалисты написали call: onAnswer: в таком тестовом случае? ----- Arender>>initialize .... collectionTasks := Dcollection new collectionTasks. "collectionTasks в Dcollection инициализирована как OrderedCollection" Arender>>renderCollectionOn: html .... html anchor callback: [ self add ]; with: 'add'. Arender>>add self call: (Crender new task: Task new). "Task - клас с описанием объектов помещаемых в колекцию collectionTasks" Сrender>>renderCollectionOn: html .... "заполнение полей экземпляра Task" html anchor callback: [ self answer: self task]; with: 'add'
-- http://groups.google.ru/group/sugr --- Вы получили это сообщение, поскольку подписаны на группу Russian Smalltalk User Group. Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес [hidden email]. Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out. |
Все очень просто. Сообщение call: нужно посылать из callback блока (конечно можно использовать специальный метод, в любом случае начинаться должно все из callback.Arender>>add |res| res := self call: (Crender new).Сrender>>renderCollectionOn: html
.... "заполнение полей экземпляра Task"
html anchor callback: [ self answer: <ответ>];
with: 'add' чтобы не возвращать ответ добавить ссылку html anchor callback: [self answer: nil]; with: 'cancel' Зачем усложнять, используя дополнительный Task new,
Все можно разместить в Crender 25 сентября 2013 г., 19:34 пользователь Genosse Alex <[hidden email]> написал:
-- http://groups.google.ru/group/sugr --- Вы получили это сообщение, поскольку подписаны на группу Russian Smalltalk User Group. Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес [hidden email]. Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out. |
В 11 главе довольно подробная информация об использовании call: и answer http://book.seaside.st/book/components/calling 25 сентября 2013 г., 21:33 пользователь Nikolay Kleptsov <[hidden email]> написал:
-- http://groups.google.ru/group/sugr --- Вы получили это сообщение, поскольку подписаны на группу Russian Smalltalk User Group. Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес [hidden email]. Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out. |
Спасибо, так работает.
-- (ту главу читал, но плохо понял, возможно из-за английского, но больше думаю из-за поверхностного изложения, то что видимо само-собой разумеющиеся для авторов, для меня совсем не очевидно) А Task new всё-равно что пихать в call:, что инициализировать в переменной Crender, разве нет? -- http://groups.google.ru/group/sugr --- Вы получили это сообщение, поскольку подписаны на группу Russian Smalltalk User Group. Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес [hidden email]. Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out. |
Вызываемый объект обязательно должен быть подклассом WAComponent, где и реализован метод answer:, в противном случае не получиться "ответить" на вызов. Непонятие изложения в 11 главе возникает потому что рассматриваемый пример расположен в нескольких главах, точнее почти с самого начала. Станет более понятным если посмотреть предшествующие главы. В книге упор сделан на практику т.е. примеры требуется непосредственно проверять в действии.25 сентября 2013 г., 23:17 пользователь Genosse Alex <[hidden email]> написал:
-- http://groups.google.ru/group/sugr --- Вы получили это сообщение, поскольку подписаны на группу Russian Smalltalk User Group. Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес [hidden email]. Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out. |
In reply to this post by Genosse
Я не вижу класса с именем SeasideDynamicSVG — это же пакет, а не класс. Я подгрузил SeasideDynamicSVG-Core, но не вижу в нем ни одного класса, где перегружался бы call:onAnswer:… О каком классе речь-то?
-- -- Best regards, Dennis Schetinin 25 сентября 2013 г., 17:34 пользователь Genosse Alex <[hidden email]> написал:
-- http://groups.google.ru/group/sugr --- Вы получили это сообщение, поскольку подписаны на группу Russian Smalltalk User Group. Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес [hidden email]. Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out. |
Да SeasideDynamicSVG - это пакет, я не правильно написал
-- А в SeasideDynamicSVG- WAComponent>>call: aComponent onAnswer: aBlock "Pass control from the receiver to aComponent. The receiver will be temporarily replaced with aComponent. When #answer: is sent to aComponent, aBlock is evaluated. This can be used for continuation passing style programmation of a control flow. #call:onAnswer: does not block but a RenderNotification is immediately signaled, aborting the current callback or task processing." self == aComponent ifTrue: [ WAError signal: 'You can not call self. You''re probably missing a return somewhere' ]. self show: aComponent onAnswer: aBlock. WARenderNotification signal Правда все классы в SeasideDynamicSVG- среда, 25 сентября 2013 г., 22:11:51 UTC+4 пользователь chaetal написал:
-- http://groups.google.ru/group/sugr --- Вы получили это сообщение, поскольку подписаны на группу Russian Smalltalk User Group. Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес [hidden email]. Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out. |
"Серый шрифт", означает, что в данном пакете соответствующий класс расширяется, а не создается. То есть пакет в уже существующий класс добавляет метод (ну, или, в общем случае, перегружает уже существующий). Соответственно, call:onAnswer: определен, по-прежнему в WAComponent, и чтобы им воспользоваться, получатель должен быть пронаследован от WAComponent. А по исходному вопросу, я бы предложил на данном этапе не заморачиваться детальным изучением всех возможных вариантов и выбором наилучшего, а просто использовать первый попавшийся из тех, которые сработают в вашем случае. Как я понял, вариант, подробно расписанный Николаем, этому критерию удовлетворяет? Если да, то имеет смысл воспользоваться им и просто двигаться дальше. Рано или поздно вы столкнетесь с задачей, где понадобится другой вариант — тогда уже гораздо легче будет понять, зачем он нужен и как работает. Вообще, это глобальный принцип, работающий не только в Smalltalk-е: 1. Make it run 2. Make it right 3. Make it fast. Начните с того, чтобы ваша система заработала (хоть как-то). А потом будет легче думать о том, как нужно это сделать "правильно". А потом можно будет уже подумать и об оптимизации, если надо.
-- Best regards, Dennis Schetinin 25 сентября 2013 г., 22:53 пользователь Genosse Alex <[hidden email]> написал:
-- http://groups.google.ru/group/sugr --- Вы получили это сообщение, поскольку подписаны на группу Russian Smalltalk User Group. Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес [hidden email]. Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out. |
Примерно в таком ключе и стараюсь действовать :) -- http://groups.google.ru/group/sugr --- Вы получили это сообщение, поскольку подписаны на группу Russian Smalltalk User Group. Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес [hidden email]. Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out. |
Free forum by Nabble | Edit this page |