2013-08-20 2 views
3

Я хочу использовать компонент backing как слой для доступа к атрибутам моего составного компонента (как определено в его интерфейсе). То, что я хотел достичь, это прочитать атрибуты моего компонента с помощью моего компонента компонента backing, где я возвращаю значение свойства предоставленного атрибута.JSF Backing Component - Composite Component - Execution Execution

public String getName() { 
    if (this.name == null) { 
     this.name = getAttributes().get("name"); 
    } 

    return this.name; 
} 

Но при установке нового значения, например. через поле ввода я хотел сохранить значение только в моих свойствах бэканга, не обновляя значения исходных свойств, переданных в качестве атрибутных аргументов моему составному компоненту.

public void setName(final String name) { 
    this.name = name; 
} 

Моя проблема теперь, когда добытчиком моего защитного компонента называется первый раз или на каком-то раннем этапе своей жизни код геттер, как показано выше, приводит к исключению StackOverflow как getAttributes.get (» name ") вызывает getter моего компонента backing (сам), вместо этого извлекает свойство/атрибут, предоставленный моему составному компоненту. Fun part использует простой getter, который возвращает this.name вместо вызова getAttributes(). Я могу установить там точку останова, а затем вызвать getAttributes.get («имя») (через отладчик), а не переполнение/вызов собственного получателя но вместо этого возвращается атрибут, предоставленный моему составному компоненту.

Я думаю, что это как-то связано с муфтой между компонентом подложки и составным компонентом. То, что когда получатель получает вызов в первый раз, никакой связи между ними не предоставляется, и поэтому вызов getAttributes.get («имя») приводит к вызову получателя моего компонента поддержки, тогда как позже вызов не вызывает его собственный getter, а вместо этого извлекает атрибут, предоставленный моему компоненту comp.

У кого-нибудь есть идеи, как решить эту проблему? Thnx заранее.

+0

Как насчет кода GetAttributes(), вы могли бы поделиться? Является ли он одним и тем же бэкбоном? – cheffe

+0

@cheffe: он просто унаследован от класса 'UIComponent'. xstring, я взял на себя смелость удалить теги '[java]' и '[ejb]' из вопроса, поскольку эта проблема не связана с этим вообще и только привлекает бесполезные комментарии, как описано выше. – BalusC

+0

Хорошо, спасибо BalsuC. – xstring

ответ

5

UIComponent#getAttributes() - это особая карта. На заданном ключе, скажем "foo", он сначала оценивает #{component.foo} как ValueExpression, который неявно вызывает метод UIComponent#getFoo(). См. Также the javadoc. Это полностью объясняет бесконечный цикл. Если метод getFoo() отсутствовал, он просто продолжал бы смотреть на «статическую» карту (которую вы можете контролировать, переопределяя UIComponent#getValueExpression()).

Вам необходимо решить свои конкретные функциональные требования по-разному. Я на самом деле было трудное время в обертывание мою голову вокруг конкретного функционального требования, но я считаю, что вам действительно нужно, чтобы определить свойства с отдельными геттеры/сеттеры, все правильно делегируя государственного помощника:

public String getLocalName() { 
    return getStateHelper().eval("localName", getAttributes().get("name")); // Note: this thus defaults to #{cc.attrs.name} when not set before. 
} 

public void setLocalName(String localName) { 
    return getStateHelper().put("localName", localName); 
} 

и а затем использовать его в композиционном реализации,

<h:inputText value="#{cc.localName}" /> 

вместо

<h:inputText value="#{cc.attrs.name}" /> 
+0

Thnx много за вашу помощь BalusC. Мое функциональное требование - сначала обновить исходные свойства, предоставленные моему компоненту comp после некоторого редактирования, когда, наконец, нажата кнопка «Сохранить».До этого мне нужно работать с копиями этих свойств, чтобы не обновлять мою модель. Надеюсь, что это решение имеет смысл или у вас есть лучшее решение для этого конкретного функционального требования? – xstring

+0

Хорошо, тогда приведенный выше ответ действительно применим. Однако вы должны привязать действие кнопки сохранения к компоненту поддержки, например 'action =" # {cc.save} ", и собрать локальные значения их получателями, а затем вернуться к исходным атрибутам, таким как' getAttributes(). Put (" name ", getLocalName());'. – BalusC

+0

Цените свою помощь сейчас и от других ответов, которые вы дали другим людям. Много уважения к вашей работе. Когда я верю, вы также являетесь одним из парней позади Primefaces, который мы здесь много используем ... – xstring

 Смежные вопросы

  • Нет связанных вопросов^_^