Windows 8 Consumer Preview版升級到 Release Preview 版後Metro應用(html5+JavaScript版)修改小結

來源:互聯網
上載者:User

  Win8出來時參加了一個活動,寫了一個APP,後來微軟那邊沒什麼動靜了,就一直沒怎麼管了,最近系統升級從Consumer Preview版升級到 Release Preview 版,VS也升級到 Visual Studio 2012 RC 後,才發現原來的APP不能運行了,於是折騰了好一陣子才OK,現在做個小結,希望可以幫到遇到相同問題的朋友。

一、WinJS版本修改

  Windows 8 Consumer Preview版中WinJS是0.6版,Release Preview 版中WinJS是1.0版,所以要把項目中的WinJS進行升級。

  這個比較簡單,大家直接按官方給出的步驟做就OK了:http://msdn.microsoft.com/en-us/library/windows/apps/JJ126963.aspx

  極少數情況下你的VS2012中沒有1.0版的WinJS:

  遇到這種情況說明你的VS沒有裝好,修複安裝就OK了。

二、滿屏,半屏,還有小屏的頁面狀態方法的修改

  這個地方我遇到的癥狀就是程式閃一下就沒了,不能開啟。

  解決方案就是把 navigator.js 中的:

appView.getForCurrentView().onviewstatechanged = this._viewstatechanged.bind(this);

  改為:

window.onresize = this._viewstatechanged.bind(this);

  上面的方案來自:http://social.msdn.microsoft.com/Forums/et-EE/winappswithhtml5/thread/d02bf608-675d-4676-a4ec-3ccbc64671f1

  但僅僅改這一個地方是不完美的,因為這個檔案裡還有與這個相關的代碼。所以還要把這行代碼稍後的:

_viewstatechanged: function (eventObject) {     (this._updateLayout.bind(this.pageControl))(this.pageElement, eventObject.viewState);},

  改為(或直接添加下面這段代碼也可以):

_resized: function (args) {      if (this.pageControl && this.pageControl.updateLayout) {          this.pageControl.updateLayout.call(this.pageControl,             
this.pageElement, appView.value, this.lastViewstate); } this.lastViewstate = appView.value;},

三、Share功能代碼的修改

  由於我的應用程式在每個詳細頁提供了Share功能,如果大家的應用中沒有這個功能就不用看這一條了。

  這個錯誤的癥狀為開啟第二個有share功能的頁面(或本頁面開啟兩次)就會出現類似下面的錯誤:  

    • SCRIPT14: Exception was thrown but not handled in user code at line 112, column 17 in ms-appx://3fa1d0d0-fb4a-48c6-8e10-f40028f54bc3/js/itemDetailPage.js
      0x8000000e - JavaScript runtime error: A method was called at an unexpected time.
      WinRT information: An event handler has already been registered
      File: itemDetailPage.js, line: 112 column: 17

  在WinJS 0.6 版中 Share的代碼大致是這樣寫的:

var dtm = Windows.ApplicationModel.DataTransfer.DataTransferManager.getForCurrentView();dtm.addEventListener("datarequested", onDataRequested);function onDataRequested(e) {    var request = e.request;    request.data.properties.title = item.title;    request.data.properties.description = "Test";    request.data.setText(item.content);}

  代碼中的item是當前頁面上繫結資料項(建立一個Grid App項目,在itemDetail.js裡就有)。

  在WinJS1.0裡報的錯大致可以看出是說 datarequested 事件已經註冊了,所以會出錯。

  一開始我嘗試的是在添加事件之前先移除這個事件,但依然出錯,後來想找到頁面unload方法,想在這個方法裡面移除事件,但貌似WinJS.UI不支援這個方法,試了好多次都不行後,找到了新的方案,就是添加一個全域變數作為標識,只註冊一次。、

  但由於上面代碼裡的item是當前頁面上繫結資料項,這就導致了Share的資料是第一次開啟詳細頁的資料,不會改變。最後直接把item.title和item.content改為從頁面上擷取,終於OK了,代碼如下:

var dtm = Windows.ApplicationModel.DataTransfer.DataTransferManager.getForCurrentView();if (!isDatarequested) {    dtm.addEventListener("datarequested", onDataRequested);    isDatarequested = true;}function onDataRequested(e) {    var request = e.request,        title = document.querySelector("article .item-title").textContent,        content = document.querySelector("article .item-content .content").textContent;    request.data.properties.title = title;    request.data.properties.description = "Test";    request.data.setText(content);}

  代碼中的 isDatarequested 是一個全域bool變數,初始值為 false 。

  目前的方案可以解決問題,但還是不太明白為什麼會出現重複註冊事件問題,如果有朋友知道請不吝指點。

四、應用掛起和啟動處理時的最佳化

  注意,這一點是最佳化,不是錯誤,所以如果你不修改也不會出錯。

  在WinJS0.6版中default.js裡有總分代碼是這樣的:

var app = WinJS.Application;app.onactivated = function (eventObject) {      if (eventObject.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {            WinJS.UI.processAll();      }};

  在WinJS1.0中要改為這樣:

var app = WinJS.Application;var activation = Windows.ApplicationModel.Activation;var nav = WinJS.Navigation;WinJS.strictProcessing();app.addEventListener("activated", function (args) {    if (args.detail.kind === activation.ActivationKind.launch) {        if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {            // TODO: This application has been newly launched. Initialize            // your application here.        } else {            // TODO: This application has been reactivated from suspension.            // Restore application state here.        }        if (app.sessionState.history) {            nav.history = app.sessionState.history;        }        args.setPromise(WinJS.UI.processAll().then(function () {            if (nav.location) {                nav.history.current.initialPlaceholder = true;                return nav.navigate(nav.location, nav.state);            } else {                return nav.navigate(Application.navigator.home);            }        }));    }});
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.