1

這是我試圖實現的不尋常的場景: 我得到了gmap模塊,其中Google地圖是異步加載的。我用下面的代碼來正確安裝谷歌地圖:Durandal如何附加視圖,並不顯示它,直到它準備好了?

composition.addBindingHandler('googleMap', { 
     init: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
      gmap = ko.utils.unwrapObservable(valueAccessor()); 

      var latLng = new gmaps.LatLng(37.774107,-122.420853); 
      var mapOptions = { 
       center:latLng, 
       zoom: 17, 
       disableDefaultUI: true, 
       mapTypeId: gmaps.MapTypeId.ROADMAP 
      }; 

      gmap.googleMap = new gmaps.Map(element, mapOptions); 
      navigator.geolocation.getCurrentPosition(onSuccess, onError); 
     } 
    }); 

我GMAP模塊是模塊,我想顯示用戶登錄後第一。所以我想在應該顯示這個模塊之前執行一些操作。在大多數情況下,我可以在canActivate方法中使用Promise,但是!在這種情況下,我的模塊沒有連接。但是我需要附加這個模塊,執行一些操作(獲取數據庫記錄,確定用戶地理位置,根據這些數據在Google Map上添加標記),並且只有在完成後才能將模塊顯示給用戶。 我怎樣才能得到這個作品?我嘗試了Promises,但它對我來說不起作用,因爲我聽attached方法,在顯示模塊之前它不會觸發。 所以問題:如何激活附加視圖模型和它的相應的視圖(激活和連接回調應該火),但沒有表現出來,直到條件

更新: 好吧,這似乎對我的問題不是很明顯可以理解。以下是我的方案:
1.我的SignIn模塊已激活。用戶應該輸入他的憑證。
2.一旦授權返回成功,Gmap模塊應該被激活並附加,但不會顯示。用戶仍然應該看到SignIn模塊和消息,如'Loading data ...'
3.Gmap模塊應該被完全加載(所有的回調應該被觸發)。我需要與DOM進行交互的可能性,這意味着應該連接模塊。但沒有顯示。
4.一旦某些條件成立,SignIn模塊將不可見,並顯示Gmap。

在激活回調中的承諾不適合這種情況,因爲在承諾解決之前視圖不會被附加。基本上,我需要這樣的成功授權之後:

router.navigate('#gmap', { show: false });
......或者......
router.attachModule('#gmap', ...{});

爲什麼我需要與DOM的互動,以及爲什麼無極激活回調不適合我?因爲我需要開始GMAP對象只能與頁面上現有GMAP帆布啓動:

composition.addBindingHandler('googleMap', { 
     init: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
      gmap = ko.utils.unwrapObservable(valueAccessor()); 
      var mapOptions = { 
      ... 

      }; 

      gmap.googleMap = new gmaps.Map(element, mapOptions); 

     } 
    }); 

和HTML:一旦查看連接

<div id="gmap-section"> 
    <div id="gmap-canvas" data-bind="googleMap:map"></div> 
</div> 

綁定纔有效。

+0

如何通過挖空可見綁定隱藏它,並在完成所有任務時設置爲true? – zewa666 2014-08-29 13:00:40

+0

當路由器從我的登錄模塊導航到我的gmap模塊時,它隱藏了我的登錄模塊。所以,我看不到gmap模塊,因爲它還沒有準備好(例如,隱藏顯示:無),我看不到我的登錄模塊,因爲它被Durandal的路由器隱藏了。 – BillyZ 2014-08-29 13:27:50

回答

0

我還沒有完全理解你的問題,但我會盡力給你一些想法。 在最佳實踐中,ViewModel應該只負責純視覺相關的東西。因此,任何繁重的計算,數據庫連接或其他任何應該被拉出到一個單獨的服務。在Durandal的情況下,這只是一個簡單的RequireJS模塊。這應該是一個單身人士,可以由多個VM需要。

通過這樣做,並不是絕對有必要立即拉入新的VM,但在SignIn中開始計算,並在完成時繼續加載新的GMapVM。

至於如何做到這一點,無論是在Sign In和Promise中啓動服務呼叫導航到GMapVM,或者如果您不喜歡Promises,可以使用Pub/Sub流程中構建的Durandal。


由於Durandals內部系統也許canActivate從GMapVM也將是從SignInVM

+0

canActivate方法中的承諾不是解決方案,因爲附加不會觸發。 canDeactivate也不是一個解決方案,因爲它是在canActivate之前進行的,所以即使canActivate也不會觸發。我想這樣做,因爲我想在顯示gmap模塊之前在地圖上添加標記。因此,用戶將只能看到帶有所有標記的加載地圖。正如你所看到的,在這種情況下,視圖邏輯與viewmodel緊密相關。或者我可以肯定,如果我在「激活」中加載所有數據,但是在「附加」上添加基於此數據的標記,那麼用戶將看不到添加標記的過程? – BillyZ 2014-08-29 18:26:27

+0

對不起雙重評論,但這裏是另一個例子:[鏈接](https://developers.google.com/maps/documentation/javascript/examples/directions-simple),你可以在這裏看到我需要gmap對象使用路線服務。例如,我想根據一些條件計算道路,並在我的gmap模塊加載時顯示它。所以用戶不應該看到建立路線的過程。在顯示gmap之前,我可能會使用估計的時間(例如,指向A的時間大約爲5分鐘)。但是我不能,因爲只有在我的gmap模塊被附加並且組合處理程序完成後,我纔可以訪問gmap。 – BillyZ 2014-08-29 18:36:03

+0

你的佈局文件「index.html」或任何被調用的應該有一個ID爲「applicationHost」的div,那麼如何在計算完成之後添加一個可見的綁定並將其設置爲false,然後再進行true? – zewa666 2014-08-30 09:04:34

0

一個合適的解決方案或替代地canDeactivate如果您的激活方法返回一個承諾Durandal的路由器會等到那個承諾路由到之前得到解決如文檔中提到的新路線 - http://durandaljs.com/documentation/Using-The-Router.html

如果您想甚至可以創建自己的承諾並使用setTimeout在您的應用程序中演示。

function activate() { 
    var promise = Q.deferred(); 
    setTimeout(function() { promise.resolve(true); }, 5000); 
    return promise; 
} 

這將返回Durandal的路由器的承諾,然後5秒鐘後它將解決承諾。您應該看到舊路線,直到承諾解決。

編輯

好了,說明明顯在這裏,但它聽起來像是你擁有的是時間激活之間的問題的意見結束並附加回調完成。在此之前,我要說一個簡單而快速的方法來完成聽起來像你正在努力完成的任務,但難以確定,因爲我不太清楚你在問什麼...

var showGmapStuff = ko.observable(false); 

function activate() { 
    var promise = Q.deferred(); 
    initializeStuff(promise); 
    return promise; 
} 

function initializeStuff(promise) { 
    connecttoserver(); 
    dootherstuff().then(finished); 

    function finished() { 
     promise.resolve(true); 
    } 
} 

function attached() { 
    showGmapStuff(true); 
} 

並且在視圖 -

<div data-bind="if: showGmapStuff"> 
    <div data-bind="gmap: mapdata"></div> 
</div> 

在這種情況下的GMAP結合將不存在,直到激活返回一個承諾和所連接的回調將showGmapStuff爲true。這種方式,而不是它是可見的假它不會被評估,直到你想要它。

+0

是的。但正如文檔中提到的,模塊激活在「激活」階段停止。我需要的「附加」階段將在稍後進行,並且使用承諾它不會觸發。在這裏最底部你可以找到回調訂單 - [鏈接](http://durandaljs.com/documentation/Hooking-Lifecycle-Callbacks) – BillyZ 2014-08-31 16:18:26

+0

你是什麼意思,你需要它,附加總是在火後。 – 2014-08-31 17:37:18

+0

我也這麼說過。所以如果我在激活中發送Promise,我的連接回調將不會觸發,直到承諾不會被解決。我需要我的模塊被連接,以便它可以使用DOM進行操作。 – BillyZ 2014-08-31 17:54:31

相關問題