2013-05-13 21 views
1

我有一種情況,我似乎無法弄清楚。如果有人知道如何解決這個問題,我很樂意聽取建議。謝謝在主幹中使用查詢字符串(1.0.0)

我有一個「全局視圖」,在應用程序的子視圖中可見,即日曆,這個日曆充當全局日曆應用程序,所以幾乎所有的視圖都使用日曆視圖&模型根據所選日期設置顯示數據。

這個日曆視圖/模型應該有一些辦法在歷史中的每個日期更改時間來存儲,這(我認爲)使用單一的URL或查詢字符串參數,均爲更改日期時完成,類似

webapp/view1?date=20120301 

當日期改變時,所以它的查詢字符串。

我想使用查詢字符串參數,因此我不必在每個路由上指定(/:date)可選參數。

問題是主幹在查詢字符串發生變化時停止發射路由更改或歷史事件,他們只是忽略Backbone.History實現上的查詢字符串,這是違反我所有的實現原因,我無法跟蹤每次querystring被更改,所以「後退」按鈕不會觸發更改事件,因此我無法更改模型上的日期以更改日曆上的日期。

我知道一個簡單的解決方案,這將只是使用「漂亮的URL」,並將該日期參數添加到每個視圖,但即時嘗試避免這一點。

有什麼建議嗎? 在此先感謝


UPDATE

最後我用「漂亮網址」之類的骨幹文檔建議,原因使用查詢字符串會給我帶來很多麻煩,用於跟蹤URL的變化和歷史,還在使用hashchange而不是pushState時不能按預期工作。

所以,我的代碼弄成這個樣子:

在你的路由器,視圖,控制器,一些地方附加,你的路由器的「路由」事件,檢查URI的日期和設置此日期日曆選擇器:

this.listenTo(myRouter, "route", this.routeChanged); 

然後,這種方法會做這樣的事情:

checkURIdateParameter: function (route, arr) { 
     var found = false; 
     for (var i = 0; i < arr.length ; i++) { 
      if (arr && arr[i] && arr[i].indexOf("date=") != -1) { 
       if (app.models.dateControl) { 
        var dateFromParameter = new Date(arr[i].substring("date=".length).replace(/\$/g, ":")); 
        dateFromParameter = (isNaN(dateFromParameter.getTime())) ? app.models.dateControl.defaults.date : dateFromParameter; 
        app.models.dateControl.set("date", dateFromParameter); 
        found = true; 
       } 
      } 
     } 
     if (!found) app.models.dateControl.set("date", app.models.dateControl.defaults.date, {changeURI:false}); 
    } 

這充當將從URI讀取PARAMS和REFL功能等在dateControl上進行更改。

應該有另一種方法,每次更改日期時都會負責將URI更新爲新的方法(以便參數與視圖同步),並且可以複製和粘貼鏈接沒有問題。

某處路由器,視圖控制器上:

this.listenTo(app.models.dateControl, "change:date", this.updateURIdateParameter); 

這是連接到具有當前日期的模型的方法,該模型是由日曆選擇器(UI控制)或更新與路線事件相關聯的方法(routeChanged,請看上面)。

此方法應該做這樣的事情:

, updateURIdateParameter: function (a, b, c) { 
     if (c && c.changeURI == false) return; //this is in case i don't want to refresh the URI case the default date is set. 

     var currentFragment = Backbone.history.fragment; 
     var newFragment = ""; 
     var dateEncoded = app.models.dateControl.get("date").toJSON().replace(/\:/g, "$"); 
     newFragment = currentFragment.replace(/\/date=([^/]+)/, "") + "/date=" + dateEncoded; 

     if (newFragment != currentFragment) { 
      app.router.navigate(newFragment, false); 
     } 
    } 

這種方法從相應的模型選擇的currentdate,解析它,則需要從Backbone.history.fragment的URL,高層對一個漂亮的正則表達式它會替換舊的日期參數(如果存在),然後附加新的編碼日期。 然後以靜音模式導航到此路由,以便檢查路由的方法不會被調用(這可以防止惱人的循環)。

我希望這會有所幫助。

回答

0

我會建議使用「漂亮的網址」。

僅在此示例中瀏覽器欄中的FYI頁面URL閃爍。

某處你Backbone.Router內:

this.route('*action', function() { 
    console.log('404'); 
}); 

this.route(/^(.*?)\?date=(\d+)$/, function(route, date) { 
    // same current route (with ?date) 
    var fragment = Backbone.history.fragment; 
    // navigate to main route (to create views etc.) 
    this.navigate(route, {trigger:true, replace:true}); 
    // silent change hash 
    this.navigate(fragment); 
}); 

this.route('any', function() { 
    // need wait for hash change 
    _.defer(function() { 
    console.log('parse date here and do what you want', window.location.hash.match(/^(.*?)\?date=(\d+)$/)); 
    }); 
}); 

this.route('route', function() { 
    // need wait for hash change 
    _.defer(function() { 
    console.log('parse date here and do what you want', window.location.hash.match(/^(.*?)\?date=(\d+)$/)); 
    }); 
}); 
+0

謝謝,最後我用「漂亮網址」,使用查詢字符串的只是給了我很多麻煩。 我使用正則表達式根據所選日期更改URL。 感謝您的時間和迴應。 – Julian 2013-05-15 14:58:49