Grails
От: mi45  
Дата: 07.02.08 10:54
Оценка:
Всем, привет!

Совсем недавно начал изучать Grails до этого был опыт работы с Groovy. Язык понравился.
5 февраля(позавчера) вышла в свет первая версия фреймворка.

Хочу узнать мнение разработчиков работавших или работающих с данным фреймворком.
Интересуют надежность, удобство использования, быстрота разработки, интеграция с Flex, GWT...
Re: Grails
От: Аноним  
Дата: 07.02.08 13:47
Оценка:
С лета прошлого года использую grails для написания проекта.
Опыт программирования в java не имел, переходил с PHP.
Могу отметить, что довольно быстро получается.

Интеграция с GWT есть в виде плагина. Сам его использую, доволен. Есть некоторые неудобства если надо прицепить дополнительную библиотеку типа gwt-ext или mygwt, проблема решилась редактированием скриптов плагина.

Очень удобно работать с grails из idea. Не идеально конечно, но каждую неделю плагин становиться лучше.

Flex тоже есть в виде плагина. Но работать с ним не довелось.

К сожалению проект еще не вышел на стадию опытной эксплуатации, поэтому ни чего не могу сказать про скорость, надежность и другие показатели
Re[2]: Grails
От: mi45  
Дата: 07.02.08 14:06
Оценка:
Здравствуйте, Аноним, Вы писали:

А>С лета прошлого года использую grails для написания проекта.

А>Опыт программирования в java не имел, переходил с PHP.
А>Могу отметить, что довольно быстро получается.

А>Интеграция с GWT есть в виде плагина. Сам его использую, доволен. Есть некоторые неудобства если надо прицепить дополнительную библиотеку типа gwt-ext или mygwt, проблема решилась редактированием скриптов плагина.

Я тоже использую gwt-ext. Интересно, а много кода нужно переписывать?
Re[3]: Grails
От: BAKAB  
Дата: 07.02.08 14:19
Оценка:
M>Я тоже использую gwt-ext. Интересно, а много кода нужно переписывать?

Нет одну строчку добавить.
${project}/plugins/gwt-0.2.3/scripts/_Internal.groovy

Ищешь в target (compileGwtModules: "Compiles any GWT modules in 'src/java'.") строчку

                Ant.classpath {
                    fileset(dir: "${gwtHome}") {
                        include(name: 'gwt-dev*.jar')
                        include(name: 'gwt-user.jar')
                    }
                    pathElement(location: "${basedir}/${srcDir}")
                }

добавлешь, и не забудь поменять путь к gwt-ext

                Ant.classpath {
                    fileset(dir: "${gwtHome}") {
                        include(name: 'gwt-dev*.jar')
                        include(name: 'gwt-user.jar')
                    }
                    pathElement(location: "${basedir}/${srcDir}")
                    pathElement(location: "${gwtHome}/extension/gwtext/gwtext.jar")
                }

Единственное неудобство это то, что еще в ${project}/lib надо положить gwtext.jar.
Так как после того как gwt плагин компилирует. Эти же классы обычным компилятор тоже цепляются (javac).
Во время разработки это не сильно мешает, но когда получишь war надо будет их удалить, чтобы место не занимали и gwtext.jar удалить из него.
Разработчик обещал этот и еще некоторые глюки исправить.

Вообще в новой версии он сильно облегчил подключение сторонних расширения для gwt.
Раньше надо было 3 файла править
Re[4]: Grails
От: mi45  
Дата: 07.02.08 14:26
Оценка:
Здравствуйте, BAKAB, Вы писали:

M>>Я тоже использую gwt-ext. Интересно, а много кода нужно переписывать?


BAK>Нет одну строчку добавить.

BAK>${project}/plugins/gwt-0.2.3/scripts/_Internal.groovy

BAK>Ищешь в target (compileGwtModules: "Compiles any GWT modules in 'src/java'.") строчку


BAK>
BAK>                Ant.classpath {
BAK>                    fileset(dir: "${gwtHome}") {
BAK>                        include(name: 'gwt-dev*.jar')
BAK>                        include(name: 'gwt-user.jar')
BAK>                    }
BAK>                    pathElement(location: "${basedir}/${srcDir}")
BAK>                }

BAK>

BAK>добавлешь, и не забудь поменять путь к gwt-ext

BAK>
BAK>                Ant.classpath {
BAK>                    fileset(dir: "${gwtHome}") {
BAK>                        include(name: 'gwt-dev*.jar')
BAK>                        include(name: 'gwt-user.jar')
BAK>                    }
BAK>                    pathElement(location: "${basedir}/${srcDir}")
BAK>                    pathElement(location: "${gwtHome}/extension/gwtext/gwtext.jar")
BAK>                }

BAK>

BAK>Единственное неудобство это то, что еще в ${project}/lib надо положить gwtext.jar.
BAK>Так как после того как gwt плагин компилирует. Эти же классы обычным компилятор тоже цепляются (javac).
BAK>Во время разработки это не сильно мешает, но когда получишь war надо будет их удалить, чтобы место не занимали и gwtext.jar удалить из него.
BAK>Разработчик обещал этот и еще некоторые глюки исправить.

BAK>Вообще в новой версии он сильно облегчил подключение сторонних расширения для gwt.

BAK>Раньше надо было 3 файла править

Радует, что один и что скоро исправят Спасибо!
Re[4]: Grails
От: unreger  
Дата: 21.03.08 06:42
Оценка:
Что-то у меня не получается. Все компилируется без ошибок, но на самой странице $wnd.Ext has no properties
Использую Идею, grails 1.0.1, gwt плагин через grails install-plugun. _Internal.groovy поправил.
Если не трудно, собери пустой проект (какую-нибудь кнопку выведи) и выложи архивом где-нибудь.
Или сравним:
nb — корень
\lib — gwtext.jar
...
\plugins\gwt-0.2.4\ ...
сейчас выглядит так
...
            echo(message: "Module: ${moduleName}")
            java(classname: 'com.google.gwt.dev.GWTCompiler', fork: 'true') {
                // Have to prefix this with 'Ant' because the Init
                // script includes a 'classpath' target.
                Ant.classpath {
                    fileset(dir: "${gwtHome}") {
                        include(name: 'gwt-dev*.jar')
                        include(name: 'gwt-user.jar')
                    }
                    fileset(dir: "${basedir}/lib") {
                        include(name: 'gwtext.jar')
                    }

                    pathElement(location: "${basedir}/${srcDir}")
                    pathElement(location: "${basedir}/lib/gwtext.jar")
                }
                arg(value: '-out')
                arg(value: outputPath)
                arg(value: moduleName)
            }
...


\src\java\test\client\test.java подобрал пример попроще из demo

package test.client;


import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.gwtext.client.widgets.ColorPalette;
import com.gwtext.client.widgets.Panel;
import com.gwtext.client.widgets.Viewport;
import com.gwtext.client.widgets.event.ColorPaletteListenerAdapter;
import com.gwtext.client.widgets.form.TextField;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class TestGWT implements EntryPoint {
    /**
     * This is the entry point method.
     */
    public void onModuleLoad() {

        Panel panel = new Panel();
        panel.setBorder(false);
        panel.setPaddings(15);

        VerticalPanel verticalPanel = new VerticalPanel();
        verticalPanel.setSpacing(15);

        final TextField textField = new TextField("Color");
        textField.setWidth(146);

        ColorPalette colorPalette = new ColorPalette();
        colorPalette.addListener(new ColorPaletteListenerAdapter() {
            public void onSelect(ColorPalette colorPalette, String color) {
                textField.setStyle("background-color:" + color + ";background-image:none;");
                textField.setValue(color);
            }
        });

        colorPalette.setTitle("Pick a color");
        verticalPanel.add(colorPalette);
        verticalPanel.add(textField);

        panel.add(verticalPanel);
        
        RootPanel.get().add(panel);
      }



\web-app\gwt\ тут все что после gwt компилятора получется

компилирую как grails application
Re[5]: Grails
От: BAKAB  
Дата: 21.03.08 07:49
Оценка: 2 (1)
Здравствуйте, unreger, Вы писали:

U>Что-то у меня не получается. Все компилируется без ошибок, но на самой странице $wnd.Ext has no properties

U>Использую Идею, grails 1.0.1, gwt плагин через grails install-plugun. _Internal.groovy поправил.

В версии плагина gwt-0.2.4 не надо уже править файл _Internal.groovy надо просто в {project}/lib/gwt положить библиотеку.
Ошибка $wnd.Ext has no properties может возникать в том случае если на странице (gsp, jsp, html) нет загрузки ext библиотек.
Соответсвено ext библиотеку надо тоже загрузить и разместить в проекте. Я для себя выбрал каталог {project}/js/ext

<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
    <title>Test</title>

    <link rel="stylesheet" type="text/css" href="${createLinkTo(dir: 'js/ext/resources/css', file: 'ext-all.css')}"/>
    <script type="text/javascript" src="${createLinkTo(dir: 'js/ext/adapter/yui', file: 'yui-utilities.js')}"></script>
    <script type="text/javascript" src="${createLinkTo(dir: 'js/ext/adapter/yui', file: 'ext-yui-adapter.js')}"></script>
    <script type="text/javascript" src="${createLinkTo(dir: 'js/ext', file: 'ext-all.js')}"></script>
    <script type="text/javascript" charset="utf-8" src="${createLinkTo(dir: 'js/ext', file: 'ext-lang-ru.js')}"></script>
</head>
.....

Обратите внимание что если таг script закрыт в стиле xml то загрузка не происходит (актуально для firefox).

То есть так делать не надо js-скрипт не загружается в firefox-е:
    <script type="text/javascript" src="${createLinkTo(dir: 'js/ext', file: 'ext-all.js')}" />


надо писать:
    <script type="text/javascript" src="${createLinkTo(dir: 'js/ext', file: 'ext-all.js')}"></script>


U>Если не трудно, собери пустой проект (какую-нибудь кнопку выведи) и выложи архивом где-нибудь.

Сейчас времени нет. Может в выходные соберу пустой проект с примером для IDEA

U>компилирую как grails application

Про grails application ни чего не нашел! Может у меня задачи другие
Я компилирую как grails run-app так как файлы в проекте разложены не так как рекомендует google.

Надеюсь смог помочь, если нет пиши, будет стимул собрать пустой проект
Re[6]: Grails
От: unreger  
Дата: 21.03.08 10:42
Оценка:
BAK>[code]
BAK><%@ page contentType="text/html;charset=UTF-8" %>
BAK><html>
BAK><head>
BAK> <title>Test</title>

BAK> <link rel="stylesheet" type="text/css" href="${createLinkTo(dir: 'js/ext/resources/css', file: 'ext-all.css')}"/>

BAK> <script type="text/javascript" src="${createLinkTo(dir: 'js/ext/adapter/yui', file: 'yui-utilities.js')}"></script>
BAK> <script type="text/javascript" src="${createLinkTo(dir: 'js/ext/adapter/yui', file: 'ext-yui-adapter.js')}"></script>
BAK> <script type="text/javascript" src="${createLinkTo(dir: 'js/ext', file: 'ext-all.js')}"></script>
BAK> <script type="text/javascript" charset="utf-8" src="${createLinkTo(dir: 'js/ext', file: 'ext-lang-ru.js')}"></script>
BAK></head>
BAK>.....

BAK>Надеюсь смог помочь, если нет пиши, будет стимул собрать пустой проект


Спасибо!
Re[5]: Grails
От: unreger  
Дата: 27.03.08 11:51
Оценка:
За неделю слегка поразбирался с контролами.
Но теперь не совсем понятно как совмещаются controller от grails и java-класс от gwt-ext для страницы.

Вот grails:
доменный класс
контроллер к нему
за view часть теперь отвечает gwt-ext

пойдем с другой стороны:
gsp страница (практически пустая — только подключаются библиотеки, будет формироваться динамически)
java-класс к этой странице

ээээ.... а теперь как?
Что и где размещать?
Вот пусть будет


class Test {
   String testValue
}

class TestController {
   def view() { //-видимо нужна функция а не action?
       [test: Test.list()]
   }
}



Как теперь вывести список на страницу? В случае чистого grails я бы воспользовался gsp тегом, но сейчас страница динамически строится по java коду. Допустим, из java класса я вызову функцию из контроллера, получу список, потом начну по нему идти, формируя новый список уже как gwt-ext объект. Как-то это неправильно. И как быть с action? И вообще, есть ли смысл в grails-контроллере?

Ну и вопрос на будущее — а если я захочу добавить еще и ajax обновление, то как-то надо разместить <div> теги. Видимо через setHtml?
Но тогда все что дальше внутри тега — руками формировать html? (Например, список, который обновляется через ajax)
Re[6]: Grails
От: BAKAB  
Дата: 01.04.08 11:56
Оценка:
Здравствуйте, unreger, Вы писали:

U>За неделю слегка поразбирался с контролами.

U>Но теперь не совсем понятно как совмещаются controller от grails и java-класс от gwt-ext для страницы.

Тот же этот вопрос меня мучает.
В своем проекте использую контроллер только для того, чтобы определить какое gwt приложение показывать.
Передачу параметров в gwt-приложение осуществляю через json объекты или ajax (GWT-RPC)
Re[7]: Grails
От: mi45  
Дата: 07.04.08 11:36
Оценка:
Здравствуйте, BAKAB, Вы писали:

BAK>Здравствуйте, unreger, Вы писали:


U>>За неделю слегка поразбирался с контролами.

U>>Но теперь не совсем понятно как совмещаются controller от grails и java-класс от gwt-ext для страницы.

BAK>Тот же этот вопрос меня мучает.

BAK>В своем проекте использую контроллер только для того, чтобы определить какое gwt приложение показывать.
BAK>Передачу параметров в gwt-приложение осуществляю через json объекты или ajax (GWT-RPC)

Решение здесь: http://geekyryan.blogspot.com/2007/12/gwt-ext-and-grails-just-works.html
Re[8]: Grails
От: unreger  
Дата: 10.04.08 09:37
Оценка:
Здравствуйте, mi45, Вы писали:

M>Здравствуйте, BAKAB, Вы писали:


BAK>>Здравствуйте, unreger, Вы писали:


U>>>За неделю слегка поразбирался с контролами.

U>>>Но теперь не совсем понятно как совмещаются controller от grails и java-класс от gwt-ext для страницы.

BAK>>Тот же этот вопрос меня мучает.

BAK>>В своем проекте использую контроллер только для того, чтобы определить какое gwt приложение показывать.
BAK>>Передачу параметров в gwt-приложение осуществляю через json объекты или ajax (GWT-RPC)

M>Решение здесь: http://geekyryan.blogspot.com/2007/12/gwt-ext-and-grails-just-works.html


Спасибо за ссылку, хотя и тяжело читается.
Там используется RequestBuilder и RequestCallback из gwt,
НО, можно ведь сделать:


   def listJSON = {
        def testList = Test.list()
        render(builder: 'json') {
            totalCount(testList.size())
            data {  //data - название секции (произвольное) в json документе
                for (t in testList) {
                    test(strField: t.strField, intField: t.intField)
                }
            }
        }
    }



public void onModuleLoad() {
        //вывод таблицы с использованием json из контроллера
        Panel panel = new Panel();
        panel.setBorder(true);
        panel.setPaddings(15);
        panel.setWidth(700);
        panel.setHeight(500);
        panel.setBodyBorder(true);

        HttpProxy dataProxy = new HttpProxy("/nb-gwt/test/listJSON");
        RecordDef recordDef = new RecordDef(
                new FieldDef[]{
                        new StringFieldDef("strField"),
                        new IntegerFieldDef("intField")
                }
        );

        JsonReader reader = new JsonReader(recordDef);
        reader.setRoot("data");
        reader.setTotalProperty("totalCount");

        final Store store = new Store(dataProxy, reader, true);
        store.load();

        ColumnModel columnModel = new ColumnModel(new ColumnConfig[]{
                new ColumnConfig("Строка", "strField", 100, true),
                new ColumnConfig("Число", "intField", 75, true)
        });


        GridPanel grid = new GridPanel();
        grid.setStore(store);
        grid.setColumnModel(columnModel);
        grid.setWidth(375);
        grid.setHeight(350);
        grid.setTitle("Json Grid");
        grid.setFrame(true);
        grid.stripeRows(true);
        grid.setIconCls("grid-icon");
        panel.add(grid);

        RootPanel.get().add(panel);
}


это работает, чуть позже проверю, работает ли submit и надо ли принимать в контроллере именно JSON

        // из http://www.gwt-ext.com/demo/#loadSubmitXmlForm:
        final Button submitBtn = new Button("Submit", new ButtonListenerAdapter() {
             public void onClick(Button button, EventObject e) {
                 /*formPanel.getForm().submit("data/xml-errors.xml", null, Connection.GET,
                                             "Saving Data...", false);*/

                 formPanel.getForm().submit("/nb-gwt/test/saveJSON"); //обращаемся к action saveJSON от TestController
             }
         });
Re[9]: Grails
От: BAKAB  
Дата: 10.04.08 09:44
Оценка:
Уважаемые кому удалось подружить jasper и acegi в grails?
Re[9]: Grails
От: unreger  
Дата: 10.04.08 10:50
Оценка:
U>это работает, чуть позже проверю, работает ли submit и надо ли принимать в контроллере именно JSON

вобщем вот, работает с обычным, автоматически сгенерированным action


 Panel panel = new Panel();
        panel.setBorder(false);
        panel.setPaddings(15);

        //setup form data reader
        RecordDef recordDef = new RecordDef(
                new FieldDef[]{
                        new StringFieldDef("strField"),
                        new IntegerFieldDef("intField")
                }
        );

        JsonReader reader = new JsonReader(recordDef);
        reader.setRoot("data");
        reader.setTotalProperty("totalCount");

        final FormPanel formPanel = new FormPanel(Position.RIGHT);
        formPanel.setFrame(true);
        formPanel.setTitle("XML Form");
        formPanel.setWidth(400);
        formPanel.setLabelWidth(75);
        //set reader and error reader
        formPanel.setReader(reader);

        //add some fields
        FieldSet fieldSet = new FieldSet("Contact Information");
        fieldSet.add(new TextField("Строка", "strField", 100));
        fieldSet.add(new TextField("Число", "intField", 75));

        formPanel.add(fieldSet);  

        final Button submitBtn = new Button("Submit", new ButtonListenerAdapter() {
            public void onClick(Button button, EventObject e) {
                /*formPanel.getForm().submit("data/xml-errors.xml", null, Connection.GET,
              "Saving Data...", false);*/

                formPanel.getForm().submit("/nb-gwt/test/save");
            }
        });

        formPanel.addButton(submitBtn);
        panel.add(formPanel);
        RootPanel.get().add(panel);


Теперь главный вопрос — как строить приложение?
Чего куда выносить. И чем лучше пользоваться. И когда.
Вот formPanel.getForm().load("/nb-gwt/test/listJSON"); или HttpProxy dataProxy = new HttpProxy("/nb-gwt/test/listJSON"); например?
Re[10]: Grails
От: unreger  
Дата: 10.04.08 11:06
Оценка:
Здравствуйте, BAKAB, Вы писали:

BAK>Уважаемые кому удалось подружить jasper и acegi в grails?


есть вот такое мнение
http://voituk.kiev.ua/2007/10/17/2007-is-year-of-groovy/

#
Евгений Потапенко Says:
October 17th, 2007 at 10:55 pm

фильтры http://grails.codehaus.org/Filters

то есть пишем в conf директории класс заканчивающийся на Filter и получаем перехват запросов где можем сделать тот же мехинизм идентификации. C Acegi нужно было лезть в спринг и делать практически тоже самое (что почемуто противно, к хорошему привыкаешь ). Раньше я делал через beforeInterceptor, что не удобно тем, что нужно наследоваться контроллеру от класса что не приятно, наследоваться хотчется например от другого, а во-вторых, каждому контроллер нужно было проверять, не забыл ли, а тут все сразу в одном месте. Конечно все это можно было реализвать просто сервлет-фильтрами но ведь коль в Граилс, то зачем лезть в такие дебри.

а эвенты ( http://grails.codehaus.org/GORM+-+Events)- ну это sql-триггер-подобный функционал. Раньше тоже можно было наверное перехватить .save(), delete() итд, а тут вот оно, встроенное


а за это пример рабочий сюда положи (если через фильтры будешь делать конечно)
Re: Grails
От: unreger  
Дата: 08.05.08 06:28
Оценка:
подводя итог
совершенно разочаровался в gwt-ext
вокруг каждого компонента наворачивается десяток <div> и что-то поправить в стиле практически невозможно
так и не смог добиться нужных отступов и размеров элементов
провозился с этим в общей сложности не меньше двух недель, только маты

посмотрел альтернативы
у грайлс есть плагин для echo2
второй день разбираю — понравилось
генерация идет из groovy класса, что не может не радовать. меня.
все просто и ясно, сразу удалось сделать дизайн, который так и не осилил на gwt-ext
вверху полоса заголовка из логотипа, собственно заголовка и иногда появляющегося логина
слева баян с командами, потом центр и подвал
ненарадуюсь
рекомендую всем

ЗЫЖ напоминаю, что в груви нет inner anonimous classes, для реализации интерфейсов используются замыкания
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.