posts - 176, comments - 240, trackbacks - 0, articles - 7

          PageFlow: Managed Navigation

          Posted on 2006-11-05 20:35 canonical 閱讀(2310) 評(píng)論(7)  編輯  收藏 所屬分類: Witrix開發(fā)平臺(tái)
          ? 按照Tim Berners-Lee的原始設(shè)想,互聯(lián)網(wǎng)的核心概念是超鏈接(hyperlink), 每一個(gè)可訪問的資源都具有自己的URI(Universal Resource Identifier), 我們通過唯一的url可以訪問到這些資源。從概念上說,每一個(gè)頁面可以由一個(gè)兩元組[title, url]來進(jìn)行描述,title是url顯示在界面上時(shí)的可讀表述。在這一描述下,我們可以建立基本的頁面瀏覽模型,包括瀏覽歷史模型:我們可以把瀏覽過的頁面保存在瀏覽歷史列表中,通過選擇歷史列表中的條目實(shí)現(xiàn)頁面跳轉(zhuǎn)。但是隨著網(wǎng)頁的動(dòng)態(tài)性不斷增加,頁面的資源語義逐漸喪失,url所對(duì)應(yīng)的不再是一種靜態(tài)的資源表述概念,而逐漸演變成為一種動(dòng)態(tài)的訪問函數(shù). 例如
          ? /view.jsp?objectName=MyObj&objectEvent=ViewDetail&id=1
          ? 一個(gè)url模式所對(duì)應(yīng)的網(wǎng)頁個(gè)數(shù)在理論上可能是無限多的. 從單一數(shù)據(jù)值到函數(shù)是系統(tǒng)復(fù)雜性本質(zhì)上的一種飛躍. 為了不致在這種無限的世界中迷失方向,我們顯然需要對(duì)于瀏覽過程進(jìn)行更加有效的組織,建立更加有約束性的導(dǎo)航模型. 一種常見的導(dǎo)航模式是在頁面的上方顯示一條線性的導(dǎo)航路徑, 與瀏覽歷史模型不同的是, 頁面轉(zhuǎn)換時(shí)不是
          ? list > view item 1 ==>? list > view item 1 > view item 2
          而是
          ?? list > view item1 ==> list > view item2
          ? 為了支持導(dǎo)航路徑, 最簡(jiǎn)單的方式是將頁面模型擴(kuò)展為三元組[id, title, urlExpr], 其中urlExpr是動(dòng)態(tài)表達(dá)式, 而id是固定的值. 例如 id=view, urlExpr=/view.jsp?objectName=MyObj&objectEvent=ViewDetail&id=${id}
          ? 導(dǎo)航路徑的變化規(guī)則為navHistory.removeAfter(newPage.id).add(newPage)
          ? 為了進(jìn)一步約化導(dǎo)航路徑, 可以將頁面模型擴(kuò)展為
          ? [id, title, urlExpr, group, before, beforeGroup],
          ? 其中g(shù)roup定義了頁面的分組, 同組的頁面在導(dǎo)航路徑中相互替代, 而before和beforeGroup定義了頁面在導(dǎo)航路徑中的相對(duì)順序. 例如對(duì)于
          ? [id='list' beforeGroup="detail"] [id='view' group='detail'] [id='update' group='detail']
          在頁面轉(zhuǎn)換時(shí), 導(dǎo)航路徑變化不是
          ? list > view item1 ==> list > view item1 > update item1
          而是
          ? list > view item1 ==> list > update item1
          ? 在以上的頁面模型中, 每一個(gè)id對(duì)應(yīng)的是一個(gè)不同的頁面模板(頁面布局), 但是有時(shí)我們也需要在同一個(gè)頁面布局中瀏覽無限分級(jí)的欄目, 此時(shí)可以將頁面模型擴(kuò)展為
          ? [id, title, urlExpr, group, before, beforeGroup, path]
          ?
          ? 將以上的導(dǎo)航模型應(yīng)用于一般的web應(yīng)用時(shí)還需要克服一個(gè)小小的困難: 動(dòng)態(tài)url的副作用. 例如/update.do?id=1&value=2這種具有動(dòng)作語義的url訪問直接破壞了頁面的瀏覽模型,例如現(xiàn)在我們不再能夠按F5鍵刷新頁面,不能通過window.location=window.location調(diào)用來刷新頁面,在頁面回退時(shí)我們也將遇到種種困難。為了防止重復(fù)提交,一種常見的設(shè)計(jì)模式是分離POST和GET方法,即通過Form POST向上提交數(shù)據(jù),處理完畢后通過redirect指令通知瀏覽器再次發(fā)起GET方法得到新的頁面.具體做法如下??
          ??? /redirect_after_action.do?id=1&value=2
          ? 在執(zhí)行完action之后, 服務(wù)器調(diào)用response.sendRedirect(get_url), 通知前臺(tái)瀏覽器使用新的url重新取回頁面. 這樣最終我們可以確保所有頁面都是可以通過url直接訪問的(沒有隱含的post參數(shù)),而且是可以重復(fù)訪問的(無副作用因而可以反復(fù)刷新)!
          ? 另一種方式是使用ajax方式提交更新請(qǐng)求,當(dāng)ajax訪問成功后, 在回調(diào)函數(shù)中進(jìn)行頁面跳轉(zhuǎn).例如:
          ? new js.Ajax().setObjectName('Test')
          ????? .setObjectEvent('Update').addForm(myForm)
          ????? .callRemote(function(returnValue){
          ??????? window.location = '/view.jsp?id=1';
          ????? })??
          這里我們也可以根據(jù)returnValue的不同選擇跳轉(zhuǎn)到不同頁面.
          ? 在Witrix平臺(tái)中, 基于Jsplet框架我們定義了PageFlow對(duì)象, 它將可配置的導(dǎo)航模型引入到任意頁面的組織過程中. 在跳轉(zhuǎn)到一個(gè)新的頁面的時(shí)候, 訪問url如下:
          ? /pageflow.jsp?objectName=MyNav&objectEvent=NavToPage&_pageId=view&id=3
          在重新訪問歷史頁面的時(shí)候,只需要
          ?/pageflow.jsp?objectName=MyNav&objectEvent=NavToHistoryPage&_pageId=view
          ? 基于jsplet框架的對(duì)象化特性,MyNav對(duì)象在session中保持了flow的所有狀態(tài)變量,不需要任何框架上特殊的支持。我們可以在任意頁面跳出pageflow, 并在任何時(shí)刻選擇跳回pageflow, 這些動(dòng)作不會(huì)影響到flow對(duì)象的狀態(tài)。而通過objectScope的設(shè)置我們可以精細(xì)的控制flow對(duì)象的生命周期。同時(shí)基于對(duì)象化設(shè)置,訪問頁面時(shí)我們只需要資源的相對(duì)名稱(relative identifier), 例如對(duì)于各種不同的flow, 頁面id都可以叫做view, 通過_pageId=view來訪問。
          ? Apache軟件基金會(huì)旗下有一個(gè)beehive項(xiàng)目, http://beehive.apache.org/docs/1.0m1/pageflow/pageflow_overview.html, 其中也定義了所謂pageflow的概念, 這是始創(chuàng)于BEA的一項(xiàng)技術(shù). 但是與Witrix Page Flow不同的是, Beehive Page Flow的核心概念仍然是從struts引申而出的action的概念,所謂的flow是action的連接,而不是通過資源id之間的連接。雖然beeive宣稱支持各種對(duì)象injection, 并且管理了flow對(duì)象的生命周期,但是它并沒有規(guī)范出this指針這一面向?qū)ο笞钪匾母拍钪弧itrix Page Flow關(guān)注的重點(diǎn)是已存在的頁面之間的有效組織, 它所描述的是某種具有靜態(tài)資源語義的頁面模板之間的關(guān)聯(lián), 這種關(guān)聯(lián)是較松散的,而不是通過action強(qiáng)關(guān)聯(lián)的. 實(shí)際上基于Ajax技術(shù)和jsplet框架的消息路由機(jī)制, 在每一個(gè)頁面上都可以進(jìn)行多種業(yè)務(wù)操作,甚至更換頁面,而不發(fā)生pageId的變動(dòng), 并不是所有的操作過程都需要在page flow描述中對(duì)外暴露。另外一個(gè)比較細(xì)節(jié)化的不同之處是Beehive使用Java Annotation, 而Witrix PageFlow使用xml描述文件, 并實(shí)現(xiàn)了pageflow的繼承和部分覆蓋等高級(jí)構(gòu)造方法. 使用xml描述文件的必要性在于需要復(fù)用WebAction, 支持復(fù)雜的變換操作, 并集成tpl模板引擎等. Annotation的方式看似簡(jiǎn)單,但這種簡(jiǎn)單性同時(shí)將系統(tǒng)中的所有組分綁定到了一起, 它也不允許復(fù)雜的變換操作的存在. 實(shí)際上Beehive的目標(biāo)并不是真正支持頁面編制(包括頁面上的頁面操作)和頁面組織的分離.

          Feedback

          # re: PageFlow: Managed Navigation  回復(fù)  更多評(píng)論   

          2006-11-06 08:53 by pear
          不好意思,問個(gè)問題,我對(duì)PageFlow不是很理解,是不是有了PageFlow,那么頁面部分用部分刷新后可以導(dǎo)航回原來的狀態(tài)呢?
          剛開始我還以為PageFlow是一個(gè)大于request,小于session的用來保存東西的東東。

          # re: PageFlow: Managed Navigation  回復(fù)  更多評(píng)論   

          2006-11-06 22:40 by canonical
          一種flow關(guān)注的重點(diǎn)當(dāng)然是協(xié)調(diào)某種類型實(shí)體之間的動(dòng)態(tài)關(guān)系,這其中必然需要一種機(jī)制來保持狀態(tài)信息。PageFlow肯定需要一種大于request而小于session的狀態(tài)保持機(jī)制. Jsplet框架就提供了這種機(jī)制,而PageFlow是運(yùn)行在其上的一個(gè)引擎。

          # re: PageFlow: Managed Navigation  回復(fù)  更多評(píng)論   

          2006-11-07 13:28 by pear
          @canonical
          這么說,我們可以用Jsplet來保存數(shù)據(jù)庫查出來的東西了,請(qǐng)問這樣做有問題嗎?如果不想把數(shù)據(jù)庫查出來的數(shù)據(jù)放到session里面,想問問是不是大家都只是把信息(除了用戶信息)放到request里面?或者我們最好把查出來的數(shù)據(jù)放到哪里比較好?

          # re: PageFlow: Managed Navigation  回復(fù)  更多評(píng)論   

          2006-11-07 23:27 by canonical
          數(shù)據(jù)到底是保存在session中還是request中,對(duì)于這個(gè)問題,基本上它的答案就是應(yīng)該保存在哪里就保存到哪里。 對(duì)于一般簡(jiǎn)單的網(wǎng)頁,應(yīng)該少在session中存放變量,而對(duì)于復(fù)雜的企業(yè)應(yīng)用,在session中保持狀態(tài)是必要的,不過查出的數(shù)據(jù)一般放在request中就可以了。

          # re: PageFlow: Managed Navigation  回復(fù)  更多評(píng)論   

          2007-01-03 00:10 by 江上一葉舟
          前一段時(shí)間做一個(gè)工作流,用的是Websphere Process Server,由于中國式的工作流與國外的大不相同,諸如領(lǐng)導(dǎo)審批類的人工審批節(jié)點(diǎn)占據(jù)了大多數(shù)于是我們的團(tuán)隊(duì)遇到了困難,即一個(gè)人審批過后接下去可能要接著審批,也可能就交給下一個(gè)人來審批,可能此人審批完畢后要將控制權(quán)交還給流程引擎,而流程引擎卻無法讓我們的頁面自動(dòng)跳轉(zhuǎn),為此我們咨詢了IBM美國實(shí)驗(yàn)室的WPS高級(jí)架構(gòu)師,他說IBM將在2006年底推出WPS的最新版本,其中引入了PageFlow的概念,由頁面來驅(qū)動(dòng)流程的進(jìn)行,一番討論后對(duì)PageFlow有了一些了解,今見此文,更有了一些自己的見解,十分感謝作者。

          # re: PageFlow: Managed Navigation  回復(fù)  更多評(píng)論   

          2007-01-03 16:15 by canonical
          Workflow中需要頁面和流程配合的部分在Witrix中主要通過前臺(tái)js選擇實(shí)現(xiàn),流程引擎實(shí)現(xiàn)的是事件響應(yīng)而不是驅(qū)動(dòng)界面。 這里倒不太用得上我所謂的PageFlow。 實(shí)際上我是反對(duì)基于action的flow設(shè)計(jì)的。

          # re: PageFlow: Managed Navigation  回復(fù)  更多評(píng)論   

          2007-05-29 00:20 by ww
          very good@pear
          主站蜘蛛池模板: 孟连| 邢台县| 堆龙德庆县| 镇安县| 崇明县| 和硕县| 诸城市| 攀枝花市| 高雄县| 富蕴县| 大邑县| 黑水县| 大余县| 鹤岗市| 宝山区| 尼勒克县| 绿春县| 涡阳县| 离岛区| 龙岩市| 平塘县| 吕梁市| 林州市| 左贡县| 灵丘县| 长泰县| 稻城县| 玛沁县| 奉贤区| 吉安市| 虞城县| 宁阳县| 湖州市| 九江县| 信阳市| 伊金霍洛旗| 锡林郭勒盟| 孙吴县| 霍城县| 广州市| 凤台县|