জেএসএফ 2 ফেসলেটগুলিতে জেএসটিএল ... কী বোঝায়?


163

আমি শর্তসাপেক্ষে কিছুটা ফেসলেট কোড আউটপুট দিতে চাই।

সেই উদ্দেশ্যে, জেএসটিএল ট্যাগগুলি ঠিক কাজ করছে বলে মনে হচ্ছে:

<c:if test="${lpc.verbose}">
    ...
</c:if>

তবে, আমি নিশ্চিত নই যে এটি সর্বোত্তম অনুশীলন কিনা? আমার লক্ষ্য অর্জনের অন্য উপায় আছে?

উত্তর:


320

ভূমিকা

জেএসটিএল <c:xxx>ট্যাগগুলি সমস্ত ট্যাগহ্যান্ডার এবং এগুলি দেখার সময় নির্মাণের সময় কার্যকর করা হয় , আর জেএসএফ <h:xxx>ট্যাগগুলি সমস্ত ইউআই উপাদান এবং সেগুলি রেন্ডার সময় দেখার সময় কার্যকর করা হয়

লক্ষ্য করুন JSF নিজস্ব থেকে <f:xxx>এবং <ui:xxx>যারা যা না ট্যাগ শুধুমাত্র না থেকে প্রসারিত UIComponent, এছাড়াও taghandlers হয় যেমন <f:validator>, <ui:include>, <ui:define>, ইত্যাদি বেশী যা থেকে প্রসারিত UIComponentএছাড়াও JSF UI উপাদান যেমন হয় <f:param>, <ui:fragment>, <ui:repeat>, ইত্যাদি JSF UI উপাদান থেকে শুধুমাত্র idএবং bindingবৈশিষ্ট্যাবলী হয় এছাড়াও দেখার সময় সময় মূল্যায়ন। সুতরাং জেএসটিএল জীবনচক্র হিসাবে নীচের উত্তরটিও জেএসএফ উপাদানগুলির বৈশিষ্ট্য idএবং bindingবৈশিষ্ট্যের ক্ষেত্রে প্রযোজ্য ।

ভিউ বিল্ড টাইম সেই মুহুর্তে যখন এক্সএইচটিএমএল / জেএসপি ফাইলটি পার্স করে কোনও জেএসএফ উপাদান গাছে রূপান্তর করতে হয় যা তখন হিসাবে সংরক্ষণ করা UIViewRootহয় FacesContext। ভিজে রেন্ডার সময়টি সেই মুহুর্তে যখন জেএসএফ উপাদান উপাদানটি শুরু করে এইচটিএমএল তৈরি করতে চলেছে UIViewRoot#encodeAll()। সুতরাং: জেএসএফ ইউআই উপাদান এবং জেএসটিএল ট্যাগগুলি কোডিংয়ের কাছ থেকে প্রত্যাশা মতো সিঙ্কে চলবে না। আপনি এটি নিম্নরূপে এটি ভিজ্যুয়ালাইজ করতে পারেন: জেএসটিএল প্রথমে উপরে থেকে নীচে চলে যায়, জেএসএফ উপাদান উপাদান তৈরি করে, তারপরে জেএসএফের পালা আবার উপরে থেকে নীচে চলে যাওয়ার, এইচটিএমএল আউটপুট উত্পাদন করে।

<c:forEach> বনাম <ui:repeat>

উদাহরণস্বরূপ, এই ফেসলেটস মার্কআপটি 3 টি আইটেম ব্যবহার করে পুনরাবৃত্তি করছে <c:forEach>:

<c:forEach items="#{bean.items}" var="item">
    <h:outputText id="item_#{item.id}" value="#{item.value}" />
</c:forEach>

... দৃশ্য নির্মাণের সময় <h:outputText>জেএসএফ উপাদান উপাদানটিতে তিনটি পৃথক উপাদান তৈরি করে , মোটামুটি এর মতো প্রতিনিধিত্ব করা হয়:

<h:outputText id="item_1" value="#{bean.items[0].value}" />
<h:outputText id="item_2" value="#{bean.items[1].value}" />
<h:outputText id="item_3" value="#{bean.items[2].value}" />

... যা ঘুরে দেখার সময় পৃথকভাবে তাদের এইচটিএমএল আউটপুট উত্পন্ন করে:

<span id="item_1">value1</span>
<span id="item_2">value2</span>
<span id="item_3">value3</span>

মনে রাখবেন যে আপনাকে উপাদান আইডিগুলির স্বতন্ত্রতাটি ম্যানুয়ালি নিশ্চিত করতে হবে এবং ভিউ বিল্ডিংয়ের সময় সেগুলিও মূল্যায়ন করা হবে।

এই ফেসলেটস মার্কআপটি 3 টি আইটেম ব্যবহার করে পুনরাবৃত্তি করছে <ui:repeat>যা একটি জেএসএফ ইউআই উপাদান:

<ui:repeat id="items" value="#{bean.items}" var="item">
    <h:outputText id="item" value="#{item.value}" />
</ui:repeat>

... ইতিমধ্যে জেএসএফ উপাদান উপাদানটিতে ইতিমধ্যে শেষ হয়েছে যার ফলে দেখাতে চলতি পুনরাবৃত্তির রাউন্ডের উপর ভিত্তি করে এইচটিএমএল আউটপুট উত্পন্ন করতে পুনরায়<h:outputText> রেন্ডার সময়টি পুনরায় ব্যবহার করা হচ্ছে :

<span id="items:0:item">value1</span>
<span id="items:1:item">value2</span>
<span id="items:2:item">value3</span>

নোট করুন যে উপাদান <ui:repeat>হিসাবে NamingContainerইতিমধ্যে পুনরাবৃত্তি সূচক উপর ভিত্তি করে ক্লায়েন্ট আইডির স্বতন্ত্রতা নিশ্চিত করেছে; idশিশু উপকরণগুলির বৈশিষ্ট্যগুলিতে এইভাবে EL ব্যবহার করাও সম্ভব নয় কারণ এটি দেখার সময় নির্মাণের সময় মূল্যায়ন করা #{item}হয় কেবলমাত্র সময় সরবরাহের সময় উপলব্ধ during একই h:dataTableএবং একই উপাদানগুলির জন্য একই true

<c:if>/ <c:choose>বনামrendered

অন্য উদাহরণ হিসাবে, এই ফেসলেটস মার্কআপ শর্তাধীনভাবে বিভিন্ন ট্যাগ যুক্ত করে যুক্ত করে <c:if>(আপনি এটির জন্যও ব্যবহার করতে পারেন <c:choose><c:when><c:otherwise>):

<c:if test="#{field.type eq 'TEXT'}">
    <h:inputText ... />
</c:if>
<c:if test="#{field.type eq 'PASSWORD'}">
    <h:inputSecret ... />
</c:if>
<c:if test="#{field.type eq 'SELECTONE'}">
    <h:selectOneMenu ... />
</c:if>

... type = TEXTকেবলমাত্র <h:inputText>জেএসএফ উপাদান উপাদানটিতে উপাদান যুক্ত করবে :

<h:inputText ... />

এই ফেসলেটস মার্কআপ করার সময়:

<h:inputText ... rendered="#{field.type eq 'TEXT'}" />
<h:inputSecret ... rendered="#{field.type eq 'PASSWORD'}" />
<h:selectOneMenu ... rendered="#{field.type eq 'SELECTONE'}" />

... শর্ত নির্বিশেষে জেএসএফ উপাদান গাছের উপরে ঠিক ঠিক সমাপ্ত হবে। এটি যখন আপনার অনেকগুলি থাকে তখন এটি "ফুলে যাওয়া" উপাদান গাছের মধ্যে শেষ হতে পারে এবং সেগুলি আসলে একটি "স্ট্যাটিক" মডেলের উপর ভিত্তি করে থাকে (অর্থাত্ fieldকমপক্ষে দেখার সুযোগের সময় পরিবর্তন হয় না)। এছাড়াও, আপনি 2.2.7 এর আগে মোজারার সংস্করণগুলিতে অতিরিক্ত সম্পত্তি সহ সাবক্লাসগুলি নিয়ে কাজ করার সময় আপনি EL সমস্যায় পড়তে পারেন।

<c:set> বনাম <ui:param>

এগুলি বিনিময়যোগ্য নয়। <c:set>সেট এল সুযোগ একটি পরিবর্তনশীল, যা শুধুমাত্র প্রবেশযোগ্য পর দৃশ্য বিল্ড সময়ে ট্যাগ অবস্থান, কিন্তু দৃশ্য যে কোন জায়গায় দৃশ্য সময় সময় রেন্ডার। <ui:param>পাসের একটি Facelet টেমপ্লেটে একটি এল পরিবর্তনশীল মাধ্যমে অন্তর্ভুক্ত <ui:include>, <ui:decorate template>অথবা <ui:composition template>। পুরানো জেএসএফ সংস্করণগুলিতে বাগ রয়েছে<ui:param> ভেরিয়েবলটি প্রশ্নযুক্ত ফেসলেট টেম্পলের বাইরেও পাওয়া যায়, এটি কখনই নির্ভর করা উচিত নয়।

<c:set>একটি ছাড়া scopeঅ্যাট্রিবিউট উপনাম মত আচরণ করবে। এটি কোনও সুযোগে ইএল প্রকাশের ফলাফলকে ক্যাশে করে না। এটি জেএসএফ উপাদানগুলি পুনরাবৃত্তি করার জন্য অভ্যন্তরে পুরোপুরি সূক্ষ্মভাবে ব্যবহার করা যেতে পারে। সুতরাং, যেমন নীচে ভাল কাজ করবে:

<ui:repeat value="#{bean.products}" var="product">
    <c:set var="price" value="#{product.price}" />
    <h:outputText value="#{price}" />
</ui:repeat>

এটি কেবলমাত্র লুপের মধ্যে যোগফল গণনা করার জন্য উপযুক্ত নয়। তার পরিবর্তে EL 3.0 স্ট্রিমটি ব্যবহার করুন :

<ui:repeat value="#{bean.products}" var="product">
    ...
</ui:repeat>
<p>Total price: #{bean.products.stream().map(product->product.price).sum()}</p>

শুধু যখন আপনি সেট scopeঅনুমোদিত মান এক সঙ্গে অ্যাট্রিবিউট request, view, session, অথবা application, তাহলে এটি অবিলম্বে দৃশ্য বিল্ড সময়ে মূল্যায়ন এবং নির্দিষ্ট সুযোগ সংরক্ষণ করা হবে।

<c:set var="dev" value="#{facesContext.application.projectStage eq 'Development'}" scope="application" />

এটি কেবল একবার মূল্যায়ন করা হবে এবং #{dev}পুরো অ্যাপ্লিকেশন জুড়ে উপলভ্য ।

জেএসএফ উপাদান উপাদান গাছ নিয়ন্ত্রণে জেএসটিএল ব্যবহার করুন

JSTL ব্যবহার করে শুধুমাত্র অপ্রত্যাশিত ফলাফল হতে পারে যখন যেমন JSF iterating উপাদান ভিতরে ব্যবহৃত হচ্ছে <h:dataTable>, <ui:repeat>ইত্যাদি, অথবা JSTL ট্যাগ বৈশিষ্ট্যাবলী যেমন JSF ঘটনার ফল উপর নির্ভর করে যখন preRenderViewবা পেশ যা দৃশ্য বিল্ড সময় পাওয়া যায় না মডেল ফর্ম মান । সুতরাং, কেবল জেএসএফ উপাদান গাছের বিল্ডিংয়ের প্রবাহ নিয়ন্ত্রণ করতে জেএসটিএল ট্যাগগুলি ব্যবহার করুন। এইচটিএমএল আউটপুট উত্পাদনের প্রবাহ নিয়ন্ত্রণ করতে জেএসএফ ইউআই উপাদানগুলি ব্যবহার করুন। varজেএসএফ উপাদানগুলির পুনরাবৃত্তিটি জেএসটিএল ট্যাগ বৈশিষ্ট্যে আবদ্ধ করবেন না । জেএসটিএল ট্যাগ বৈশিষ্ট্যে জেএসএফ ইভেন্টগুলিতে নির্ভর করবেন না।

যে কোনও সময় আপনি মনে করেন যে আপনাকে কোনও উপাদানকে ব্যাকিং শিমের সাথে বাঁধতে হবে binding, বা এর মাধ্যমে একটি দখল করতে হবে findComponent()এবং তার বাচ্চাদের একটি ব্যাকিং শিমের সাহায্যে জাভা কোড ব্যবহার করে new SomeComponent()এবং কী ব্যবহার করা উচিত নয়, তারপরে আপনাকে তত্ক্ষণাত বন্ধ করে দেওয়া উচিত এবং পরিবর্তে জেএসটিএল ব্যবহার করা উচিত। যেহেতু জেএসটিএলও এক্সএমএল ভিত্তিক, জেএসএফ উপাদানগুলিকে গতিশীলভাবে তৈরি করার জন্য প্রয়োজনীয় কোডটি এত বেশি ভাল পঠনযোগ্য এবং রক্ষণাবেক্ষণযোগ্য হয়ে উঠবে।

জেনে রাখা জরুরী যে মোস্তরার সংস্করণগুলি ২.১.১৮ এর চেয়ে পুরানো সংস্করণগুলিতে একটি জেএসটিএল ট্যাগ অ্যাট্রিবিউটে স্কোপড শিমের দৃশ্যের উল্লেখ করার সময় আংশিক অবস্থা সাশ্রয় করতে একটি বাগ পেয়েছিল। পুরো ভিউ স্কোপড শিমটি ভিউ ট্রি থেকে পুনরুদ্ধারের পরিবর্তে নতুনভাবে পুনরায় তৈরি করা হবে (কেবলমাত্র জেএসটিএল চলমান পয়েন্টে পুরো ভিউ ট্রিটি এখনও পাওয়া যায়নি)। আপনি যদি কোনও জেএসটিএল ট্যাগ অ্যাট্রিবিউট দ্বারা স্কোপড শিম ভিউতে কিছু রাজ্যের প্রত্যাশা বা সংরক্ষণ করে থাকেন তবে তা আপনার প্রত্যাশিত মানটি ফেরত দেবে না, বা এটি আসল ভিউ স্কোপড শিমের মধ্যে "হারিয়ে যাবে" যা দেখার পরে পুনরুদ্ধার করা হবে গাছ নির্মিত হয়। আপনি মোজারার ২.১.১৮ বা আরও নতুনতে আপগ্রেড করতে না পারলে আশেপাশের কাজটি হ'ল web.xmlনীচের মতো আংশিক অবস্থা সাশ্রয় বন্ধ করে দিন:

<context-param>
    <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
    <param-value>false</param-value>
</context-param>

আরো দেখুন:

জেএসটিএল ট্যাগগুলি সহায়ক (যেখানে দৃশ্য নির্মাণের সময় সত্যিকার অর্থে সঠিকভাবে ব্যবহৃত হয়) এমন কয়েকটি বাস্তব বিশ্বের উদাহরণগুলি দেখতে, নিম্নলিখিত প্রশ্ন / উত্তরগুলি দেখুন:


সংক্ষেপে

আপনার কংক্রিটের কার্যকরী প্রয়োজন অনুসারে, আপনি যদি শর্তাধীন জেএসএফ উপাদানগুলি রেন্ডার করতে চান তবে এর renderedপরিবর্তে জেএসএফ এইচটিএমএল উপাদানটিতে অ্যাট্রিবিউটটি ব্যবহার করুন , বিশেষত যদি #{lpc}কোনও জেএসএফ পুনরাবৃত্ত উপাদানগুলির যেমন পুনরাবৃত্তি আইটেমের প্রতিনিধিত্ব করে <h:dataTable>বা যেমন <ui:repeat>

<h:someComponent rendered="#{lpc.verbose}">
    ...
</h:someComponent>

অথবা, যদি আপনি করতে চান বিল্ড (তৈরি / যোগ করুন) JSF উপাদান শর্তসাপেক্ষে, তারপর JSTL ব্যবহার করতে থাকুন। এটি new SomeComponent()জাভাতে ভার্বোসালি করার চেয়ে অনেক ভাল ।

<c:if test="#{lpc.verbose}">
    <h:someComponent>
        ...
    </h:someComponent>
</c:if>

আরো দেখুন:


3
@ অকলিন: না? কিভাবে এই উদাহরণ ?
বালুসসি

1
আমি দীর্ঘ সময়ের জন্য প্রথম অনুচ্ছেদের সঠিকভাবে ব্যাখ্যা করতে পারি না (প্রদত্ত উদাহরণগুলি যদিও খুব পরিষ্কার)। অতএব, আমি এই মন্তব্যটি একমাত্র উপায় হিসাবে রেখে চলেছি। এই অনুচ্ছেদে, আমি <ui:repeat>এমন একটি ছাপে রয়েছি যে একটি ট্যাগ হ্যান্ডলার (এই লাইনটির কারণে, " জেএসএফের নিজস্ব <f:xxx>এবং <ui:xxx>... " নোট করুন যে ঠিক) <c:forEach>এবং সেইজন্য, এটি দেখার সময় মূল্যায়ন করা হয় (আবার ঠিক ঠিক মত <c:forEach>) । যদি যে তারপর সেখানে মধ্যে কোনো দৃশ্যমান কার্মিক পার্থক্য করা উচিত হবে না <ui:repeat>এবং <c:forEach>? সেই অনুচ্ছেদের অর্থটি ঠিক কী তা আমি পাই না :)
টিনি

1
দুঃখিত, আমি এই পোস্টটি আর দূষিত করব না। আমি আপনার পূর্ববর্তী মন্তব্যটি আমার নজরে নিয়েছি তবে এই বাক্যটি কি নয়, " জেএসএফের নিজস্ব <f:xxx>এবং <ui:xxx>যেগুলি ট্যাগগুলি প্রসারিত করে না UIComponentসেগুলি ট্যাগ হ্যান্ডলারও রয়েছে Note " তা বোঝানোর <ui:repeat>চেষ্টাটিও একটি ট্যাগ হ্যান্ডলার কারণ <ui:xxx>অন্তর্ভুক্ত রয়েছে <ui:repeat>? এর অর্থ এই হওয়া উচিত যে এটি প্রসারিত <ui:repeat>উপাদানগুলির মধ্যে একটি । অতএব, এটি কোনও ট্যাগ হ্যান্ডলার নয়। (তাদের মধ্যে কিছু প্রসারিত নাও হতে পারে Hence তাই, তারা ট্যাগ হ্যান্ডলারগুলি) এটি কী? <ui:xxx>UIComponentUIComponent
ক্ষুদ্র

2
@ শিরগিল: লক্ষ্য স্কোলে মূল্যায়িত মান নির্ধারণের পরিবর্তে ইএল এক্সপ্রেশনটির একটি উপকরণ তৈরি <c:set>না করেই scopescope="request"পরিবর্তে চেষ্টা করুন, যা অবিলম্বে মানটি নির্ধারণ করবে (প্রকৃতপক্ষে দেখার সময়) এবং অনুরোধের বৈশিষ্ট্য হিসাবে সেট করা হবে (যা পুনরাবৃত্তির সময় "ওভাররাইট করা হবে না")। প্রচ্ছদের অধীনে, এটি তৈরি করে একটি ValueExpressionবস্তু সেট করে ।
বালুসসি

1
@ কে। নিকোলাস: এটি ক এর আওতায় রয়েছে ClassNotFoundException। আপনার প্রকল্পের রানটাইম নির্ভরতা ভঙ্গ হয়েছে। সম্ভবত আপনি টমক্যাট-এর মতো একটি নন-জাভাইই সার্ভার ব্যবহার করছেন এবং আপনি জেএসটিএল ইনস্টল করতে ভুলে গেছেন, বা আপনি দুর্ঘটনাক্রমে জেএসটিএল 1.0 এবং জেএসটিএল 1.1+ অন্তর্ভুক্ত করেছেন। কারণ জেএসটিএল 1.0 এ প্যাকেজটি রয়েছে javax.servlet.jstl.core.*এবং জেএসটিএল 1.1 সাল থেকে এটি হয়ে গেছে javax.servlet.jsp.jstl.core.*। JSTL ইনস্টল করার জন্য সংকেত সনাক্ত করুন এখানে পাওয়া যাবে: stackoverflow.com/a/4928309
BalusC

13

ব্যবহার

<h:panelGroup rendered="#{lpc.verbose}">
  ...
</h:panelGroup>

থেক্স, দুর্দান্ত উত্তর। আরও সাধারণভাবে: জেএসটিএল ট্যাগগুলি কী এখনও বোধগম্য হয় বা আমাদের এটিকে জেএসএফ ২.০ থেকে অবহেলিত হিসাবে বিবেচনা করা উচিত?
জানুয়ারি

বেশিরভাগ ক্ষেত্রে, হ্যাঁ তবে কখনও কখনও
এগুলি

3
এইচ: প্যানেলগ্রুপ ব্যবহার করা একটি নোংরা সমাধান, কারণ এটি <span> ট্যাগ উত্পন্ন করে, যখন সি: যদি এইচটিএমএল কোডে কিছু না জুড়ে। এইচ: প্যানেলগ্রুপটি প্যানেলগ্রিডগুলির মধ্যেও সমস্যাযুক্ত কারণ এটি উপাদানগুলিকে গোষ্ঠীভুক্ত করে।
রবার 2 ডি 2

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.