2017-12-12 8 views
0

모델 개체의 필드에 바인딩 된 텍스트 필드 입력을 포함하는 양식이 있습니다. 사용자가 텍스트 필드에 데이터를 입력하면 계산을 기반으로 양식 내의 여러 다른 필드/구성 요소에 영향을 줄 수 있습니다. 내 비즈니스 로직은 서비스 계층에 캡슐화됩니다.모델 변경/재 렌더링을 사용하여 뷰를 동기화하는 방법

이론적으로 이것이 작동하도록하는 방법은 사용자가 필드를 업데이트 할 때 서비스의 논리가 적용되고 영향을받는 모든 필드가 모델에서 업데이트되는 서버 (keypress)에 대한 ajax 호출이 수행된다는 것입니다. 목적. 모델이 서버에서 업데이트되면 모델 객체의 현재 상태를 화면에 동기화하려고합니다.

전체 화면을 새로 고치는 유일한 방법은 무엇입니까? 변경된 모델의 필드에 바인딩 된 구성 요소 만 다시 렌더링하는 방법이 있습니까? 또한 화면을 새로 고치면 편집중인 필드도 업데이트됩니다.이 방법을 제외 할 수 있습니까?

이 기술에 대한 모범 사례에 관심이 있습니다.

덕분에 당신은 그냥 마크 업 ID (Component.setOutputMarkupId(true))를 가지고 있는지 확인, 원하는 구성 요소를 업데이트 할 수 있습니다 아약스와 함께

+0

AJAX 응답 콜백에서 호출되는 Javascript를 사용하여 필드를 업데이트하는 것이 가장 좋습니다. – tsolakp

답변

1

.

당신은 각각의 FormComponent S의 모델을 업데이트하기 위해 onUpdate() 콜백 AjaxFormComponentUpdatingBehavior 또는 AjaxFormChoiceComponentUpdatingBehavior와 당신이 사용할 필요가 그리고 당신은 당신이 가진 유일한 사람을 현재 양식의 모든 FormComponents를 방문 AjaxRequestTarget에 추가 FormComponent.this.getForm().visitChildren(FormComponent.class, IVisit)을 사용할 수 있습니다 업데이트되었습니다.

업데이트 또 다른 좋은 해결책은 위젯 이벤트 버스를 사용하는 것입니다. 아약스 동작에서는 이벤트를 방송 수 :

component.send(getForm(), Broadcast.BREADTH, new UIChangedEvent(target, newValue)); 

UIChangedEvent은 업데이트 된 구성 요소와 AjaxRequestTarget의 새로운 가치를 제공하여 자신의 클래스/POJO이다.

그러면 다른 FormComponent는 #onEvent()을 무시하고 이전 계산에 따라 값을 사용하여 새 값을 계산하고 대상을 사용하여 자체를 업데이트 할 수 있습니다.

+0

응답 해 주셔서 감사합니다 Martin,보기를 재 렌더링하는 것이 좋겠지 만 현재 화면에있는 것과 다른 값을 가진 필드 만 명시 적으로 "onupdate change"와 같은 동작을 추가하여 종속성을 만들지 않아도됩니다 필드 A, B, C, F, X ". 업데이트 된 것을 추가하는 것을 제안하는 경우, 개찰구를 통해 업데이트되는 필드를 결정하는 방법이 있습니까? 또는 원래 모델에 대한 참조가 있어야하고 비교 필드를 필드별로해야합니까? – kgrad

+0

업데이트 된 답변보기 희망이 충분합니다! –

+1

마틴, 개인적으로 저는 새로운 가치를 지닌 사건을 싫어합니다. 나는 그들 스스로 구성 요소에 의해 적절한 모델을 설정해야한다고 생각한다.이벤트는 모델에서 작동하는 구성 요소 (또는 파생 모델)에 의해 처리되어야하며 이러한 구성 요소는 모델의 데이터를 다시 사용합니다. 이렇게하면 '모델 업데이트 버그를 책임지는 사람이 없습니다' – RobAu

1

귀하의 태그에서 개찰구를 사용한다고 가정합니다. 개찰구는 이러한 목적으로 행동을 사용합니다. 다음 예제에서는 TextField의 입력이 변경된 경우 두 DropDownChoices를 모두 업데이트합니다. 이러한 컨트롤을 AjaxRequestTarget에 추가하기 만하면됩니다. 두 DropDownChoices의 모델은 프론트 엔드에서 다시로드되고 다시 렌더링됩니다. 또한 업데이트 할 컨트롤에 대해 setOutputMarkupId (true)를 호출해야합니다.

TextField<String> textField = new TextField<String>("input"); 
    Component dropDownA = new DropDownChoice<>("dropA").setOutputMarkupId(true); 
    Component dropDownB = new DropDownChoice<>("dropB").setOutputMarkupId(true); 

    textField.add(new AjaxFormComponentUpdatingBehavior("change") { 
     private static final long serialVersionUID = 1478280524536023725L; 

     @Override 
     protected void onUpdate(AjaxRequestTarget target) { 
      target.add(dropDownA); 
      target.add(dropDownB); 
     } 
    }); 
+0

'on' 접두어없이 이벤트 유형을 지정해야합니다. 그래서이 경우에 그것은 단지'onchange' 대신에'change'입니다. Wicket 7의 AjaxEventBehavior에서 다음 경고를 참조하십시오 : "버전 6.0.0부터 Wicket은 JavaScript 이벤트 등록을 사용하므로 이벤트 이름 '% s'에 'on'을 사용할 필요가 없습니다. '% s'만 사용하십시오. Wicket 8.x는 제공된 이벤트 이름을 조작하지 않으므로 선두에 'on'이 응용 프로그램을 손상시킬 수 있습니다. " – Tekki

+0

정보를 제공해 주셔서 감사합니다. 나는 그 사실에 대해 몰랐고 관련 성명을 변경했습니다. –