2014-10-07 5 views
0

부분 업데이트 세트가있는 필드에서 onChange 이벤트를 사용하는 경우 전에 부분 업데이트의 실행이 으로 실제 이벤트에서 SSJS 코드가 수행됩니다.부분 업데이트에서 평가 순서를 반대로하는 방법은 무엇입니까?

이것을 뒤집을 수있는 방법이 있습니까?

내 경우에는 3 개의 필드, 하나의 숨겨진 입력 값 및 계산 된 값이 있습니다.

사용자는이 세 필드에 값을 입력하고 숨겨진 구성 요소에는 위의 필드의 합계를 계산하는 수식이 있습니다. 명목 * 가격 + 수수료 = PaymentAmount.
고객은 PaymentAmount 이전에 계산 된 사전 정의 된 수수료 값을 원합니다. 내 예제에서는 0.15 %의 하드 코딩 된 값을 사용합니다.
공식은 다음이 될 것입니다 PaymentAmount = (공칭 * 가격 *의 feeDef) + (공칭 * 가격) 우리는 단지 업데이트 할 수 있도록 우리가 PaymentAmountRow으로 행을 태그 한 테이블 내부의 PaymentAmount을 설정 한

두 구성 요소.
부분적으로 업데이트하는 데 사용 된 모든 구성 요소 PaymentAmountRow하지만 지금은 1 원만 업데이트하려면 구성 부품 가격이 필요합니다. 나는 위의 모든 부분에 대한 부분 업데이트를 변경했다면,이 경우 주변 패널은 dealInfo이라고 불리웠다.하지만 놀랍게도 부분 구성 요소의 계산은 요금을 계산하는 실제 코드보다 먼저 실행된다.

I 이벤트에 사용할 수있는 모든 매개 변수를 시도했지만 그들 중 누구도 작동하지

...

<?xml version="1.0" encoding="UTF-8"?> 
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"> 
    <xp:this.resources> 
     <xp:script 
      src="/CommonSSJS.jss" 
      clientSide="false" 
     > 
     </xp:script> 
    </xp:this.resources> 
    <xp:panel id="dealInfo"> 
     <xp:this.data> 
      <xp:dominoDocument 
       var="document1" 
       formName="EquityTrade" 
      > 
      </xp:dominoDocument> 
     </xp:this.data> 
     <xp:label 
      value="Nominal" 
      id="label2" 
     > 
     </xp:label> 
     <xp:inputText 
      id="Nominal" 
      value="#{document1.Nominal}" 
     > 
      <xp:eventHandler 
       event="onchange" 
       submit="true" 
       refreshMode="partial" 
       refreshId="PaymentAmountRow" 
      > 
       <xp:this.action><![CDATA[#{javascript:print("Nominal onChange - partial PaymentAmount");}]]></xp:this.action> 
      </xp:eventHandler> 
      <xp:this.converter> 
       <xp:convertNumber type="number"></xp:convertNumber> 
      </xp:this.converter> 
      </xp:inputText> 
     <xp:br></xp:br> 
     <xp:label 
      value="Price" 
      id="label1" 
     > 
     </xp:label> 
     <xp:inputText 
      id="Price" 
      value="#{document1.Price}" 
     > 

      <xp:this.converter> 
       <xp:convertNumber type="number"></xp:convertNumber> 
      </xp:this.converter> 
      <xp:eventHandler 
       event="onchange" 
       submit="true" 
       refreshMode="partial" 
       refreshId="Fee1"> 
       <xp:this.action><![CDATA[#{javascript:print("Price onChange - update") 
var Fee1:com.ibm.xsp.component.xp.XspInputText = getComponent("Fee1"); 
var feeDef = 0.15; 
var Nominal:com.ibm.xsp.component.xp.XspInputText = getComponent("Nominal"); 
var Price:com.ibm.xsp.component.xp.XspInputText = getComponent("Price"); 
var fee = Nominal.getValue()*Price.getValue()*feeDef 
Fee1.setValue(fee); 
}]]></xp:this.action> 
      </xp:eventHandler> 
     </xp:inputText> 
     <xp:br></xp:br> 
     <xp:label 
      value="Fee 1" 
      id="label3" 
     > 
     </xp:label> 
     <xp:inputText 
      id="Fee1" 
      value="#{document1.Fee1}" 
     > 
      <xp:this.converter> 
       <xp:convertNumber type="number"></xp:convertNumber> 
      </xp:this.converter> 
      <xp:this.valueChangeListener><![CDATA[#{javascript:print("Value changed"); 
}]]></xp:this.valueChangeListener> 

      <xp:eventHandler 
       event="onchange" 
       submit="true" 
       refreshMode="partial" 
       refreshId="PaymentAmountRow" 
      ></xp:eventHandler> 
     </xp:inputText> 
     <xp:br></xp:br> 

     <xp:table> 
      <xp:tr id="PaymentAmountRow"> 
       <xp:td> 
        <xp:inputHidden 
         id="PaymentAmount" 
         value="#{document1.PaymentAmount}" 
        > 
         <xp:this.converter> 
          <xp:customConverter getAsString="#{javascript:return value.toString();}"> 
           <xp:this.getAsObject><![CDATA[#{javascript:try { 
    print("PaymentAmount calculation"); 
    var Nominal:com.ibm.xsp.component.xp.XspInputText = getComponent("Nominal"); 
    var Price:com.ibm.xsp.component.xp.XspInputText = getComponent("Price"); 
    var Fee1:com.ibm.xsp.component.xp.XspInputText = getComponent("Fee1"); 

    var nominal = Nominal.getValue(); 
    var price = Price.getValue(); 
    var fee1= Fee1.getValue(); 

    var paymentAmount = nominal * price; 
    paymentAmount+=fee1; 
    return paymentAmount; 
} catch(e){ 
    dBar.info(e); 
}}]]></xp:this.getAsObject> 
          </xp:customConverter> 
         </xp:this.converter> 
        </xp:inputHidden> 
        <xp:text 
         escape="true" 
         id="computedField14" 
        > 
         <xp:this.value><![CDATA[#{document1.PaymentAmount}]]></xp:this.value> 
         <xp:this.converter> 
          <xp:convertNumber type="number"></xp:convertNumber> 
         </xp:this.converter> 
        </xp:text> 
       </xp:td> 
      </xp:tr></xp:table> 
    </xp:panel> 
</xp:view> 

답변

1

내가 코드 또는 일부 문제를 일으키는 이해 100 % 확실하지 않다,하지만 난 그게 생각 변환기의 getAsObject()가 eventHandler의 응용 프로그램 논리를 실행하기 전에 실행 중이며 올바른 값을 얻지 못하고 있음을 나타냅니다. 그래서 여기 간다 :

XPages (그리고 JSF) 부분 리프레시주기가 여섯 단계를 통해 실행 : 1) 보기 복원 컴포넌트 트리가 그래서 우리는 HTML가 기본이되는 자바 객체로 다시 전송되는 매핑 할 수 있습니다 다시 작성합니다. 2) 요청 값 적용은 HTML에 입력 된 문자열 값을 가져와 관련 구성 요소의 submittedValue 속성에 넣습니다. 3) 프로세스 유효성 검사은 모든 변환기와 유효성 검사기를 실행하여 submittedValue 속성을 기본 데이터 형식으로 변환하고 서버에 정의 된 유효성 검사 규칙을 전달할 수 있도록합니다. 4) 모델 값 업데이트은 제출 된 값을 취합니다 (이제 데이터를 고치지 않고 데이터 모델에 적용 할 수 있습니다). 문자열을 관련 데이터 유형으로 변환하고 value 속성에 넣은 다음 submittedValue를 null로 설정합니다. (프로세스 유효성 검사 단계에서 문자열을 변환하여 내부 변수에 저장했을 수 있으므로이 단계에서 값과 submittedValue 만 업데이트하면됩니다.) 5) Invoke 응용 프로그램은 eventHandler 논리를 실행합니다. 6) 응답 렌더링은 브라우저에 대해 업데이트 된 HTML을 생성합니다.

주문을 변경할 수 없습니다. 따라서 프로세스 유효성 검사는 모델 값 업데이트 전에 실행해야합니다.그렇지 않으면 데이터 유형이 잘못 되었기 때문에 모델 값 업데이트가 중단되거나 유효하지 않은 값이 저장되어 기본 문서에 기록됩니다.

저는 변환기가 getComponent(). getValue()를 사용하고 있다고 생각합니다. 그러나 변환기의 getAsObject() 메서드가 실행될 때 프로세스 유효성 검사 단계에서 값이 설정되지 않습니다.

그래서, 당신이 실제로 필요로하는 경우 중 하나.

  • 이 getComponent() getSubmittedValue()를 사용하여 변환에 다른 구성 요소의 값을 확인하고 그에 따라 오류가 발생합니다.

또는

  • 그냥 기본 번호 변환기를 사용하고 백엔드 데이터와 상호 작용의 이벤트 핸들러에 결제 금액을 설정하는 코드를 이동 - 그래서 등 document1.Price을 받고 document1.paymentAmount 설정.

후자를 사용하는 경우 inputHidden을 피할 수 있어야합니다.

+0

Thx, 나는 그것을 시도해 볼 것입니다 ... –

+0

모든 필드를 계산하고 PaymentAmount를 설정하기 위해 이것을 사용하여 SSJS 자원에 메소드를 추가했습니다. 그럼 당신이 말했듯이 유효성/변환없이 필드를 "보통"파일로 변경했습니다. –