Grails - обновление таблицы данными, которые уже существуют во время вызова AJAX - PullRequest
2 голосов
/ 05 марта 2012

У меня небольшая дилемма, и я считаю, что это может быть проблемой дизайна. У меня есть список контактов, возвращенных в мое представление (searchResults) на основе некоторых критериев (флажки и т. Д.). По сути, расширенный поиск.

У каждого контакта есть три ссылки в наборе полей, которые позволяют редактировать, отображать детали или нажимать кнопку «ThisThis». Метод hitThis выполняет серию задач, которые будут генерировать три новых значения для контакта - возраст, размер, скорость. Когда я нажимаю эту ссылку, я хочу в основном обновить эту строку только новыми значениями (столбцы уже существуют, просто пустые).

В моем gsp есть div, содержащий таблицу, в которой отображается список searchResults. Во время отправки формы для результатов поиска я возвращаю список контактов, которые обновляют мой шаблон, в котором существует div. Это отлично работает.

В этом div у меня есть такая форма:

<td>
  <g:form>
    <fieldset class="buttons">
      <g:hiddenField name="id" value="${contactInstance?.id}" />
      <g:set var="searchResults" value="${searchResults}" /><br/>
      <g:set var="cID" value="${contactInstance?.id}" /><br/>
      <g:actionSubmit class="edit" action="edit" value="${message(code: 'Edit')}"/>
      <g:actionSubmit class="show" action="show" value="${message(code: 'Show')}"/>
      <g:remoteLink action="hitThis" value="Click Me" update="searchResultsDiv" params="[searchResults:searchResults, cID:cID]"/>
    </fieldset>
  </g:form>
</td>

Когда я выбираю удаленную ссылку для hitThis, я хочу выполнить действие, которое обновит три столбца, которые прикреплены к этой строке contactInstance в шаблоне searchResults:

Перед кликом:

myName  age  size  speed
Tom     empty empty empty

После нажатия:

myName age size speed
Tom    20   6    4.9

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

Я мог бы просто перенаправить пользователя на информационную страницу этого контакта (показать), но я бы предпочел обновить таблицу на лету.

Как я могу просто обновить div или даже строку таблицы после моего вызова HitThis и без необходимости передавать все обратно контроллеру, чтобы только передать его снова?


Edit:

Итак, мои результаты в соответствии с примером, который вы мне дали, похожи на это (имя Тед, размер 5, скорость 4:

name     size    speed
Ted54   Ted54    Ted54

Вот часть моего взгляда:

<td id="name-${contactInstance.id}"><g:render template="name" model="['contactInstance':contactInstance]"/></td>
<td id="size-${contactInstance.id}"><g:render template="size" model="['contactInstance':contactInstance]"/></td>
<td id="speed-${contactInstance.id}"><g:render template="speed" model="['contactInstance':contactInstance]"/></td>

<fieldset class="buttons">

    <g:hiddenField name="id" value="${contactInstance?.id}" />
    <g:remoteLink action="moreInfo" params="['cid':contactInstance?.id]" onSuccess="updateData(data,'${contactInstance?.id}'), updateData2(data,'${contactInstance?.id}'), updateData3(data,'${contactInstance?.id}')" >TEST</g:remoteLink>
</fieldset>

Вот мой Javascript:

    <script>
        function updateData(data, id) {
            alert(data);
            $('#name-'+id).html(data);
        }

        function updateData2(data, id) {
            alert(data);
            $('#size-'+id).html(data);
        }

        function updateData3(data, id) {
            alert(data);
            $('#speed-'+id).html(data);
        }
    </script>

И мой метод управления:

def moreInfo() {
    def contactInstance = Contact.get(params.cid)

    contactInstance.name= "Ted"
    contactInstance.size= "5"
    contactInstance.speed= "4"

    if (contactInstance.save(flush: true)) {
        println(contactInstance)
    }

    render(template:'name', model:[contactInstance:contactInstance])
    render(template:'size', model:[contactInstance:contactInstance])
    render(template:'speed', model:[contactInstance:contactInstance])
}

1 Ответ

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

Вы можете манипулировать DOM, используя javascript после того, как удаленный вызов вернется.

(Я не уверен, почему вам нужно передать весь searchResults удаленным вызовом. Это может быть довольно большая структура. Вы можете вместо этого сохранить ее в сеансе и манипулировать ею там. КонечноЭто ваше дизайнерское решение.)

Еще один способ подумать об этом - создать шаблон для формы.Затем визуализируйте этот шаблон с помощью удаленного вызова (заменив существующий внутри td).

template: _myform.gsp

  <g:form>
    <fieldset class="buttons">
      <g:hiddenField name="id" value="${contactInstance?.id}" />
      <g:set var="searchResults" value="${searchResults}" /><br/>
      <g:set var="cID" value="${contactInstance?.id}" /><br/>
      <g:actionSubmit class="edit" action="edit" value="${message(code: 'Edit')}"/>
      <g:actionSubmit class="show" action="show" value="${message(code: 'Show')}"/>
      <g:remoteLink action="hitThis" value="Click Me" update="searchResultsDiv" params="[searchResults:searchResults, cID:cID]"/>
    </fieldset>
  </g:form>

тогда ваш обычный gsp страницы может быть:

...
<tr>
  <td>
    <g:render template="myform" />
  </td>

  <td>
    <g:render template="myform" />
  </td>
</tr>
...

и в действии hitThis

def hitThis() {
    ...
    render(view: "myform")
}

наконец, используйте javascript для замены формы в 'td' на стороне клиента

...