[英]How to navigate, with history, in MVC 5 SPA template?
我在VS2013 SPA MVC-5
模板中的導航中苦苦掙扎。 我做了兩個假設(因為我找不到很好的參考),但似乎我錯了,或者工作不正常:
它認為導航基於典型的spa # url encoding
,例如,直接導航到users account management page
應該可以使用: http://localhost:18759/#/manage
我還認為,在瀏覽網站(單頁)時,我認為這些# url's
由模板中包含的默認knockout.js
文件形成的。 結合先前的假設,這將導致適當的歷史積累。
http://localhost:18759/#/manage
似乎無法導航到manage
頁面(其他# url's
也不起作用)。
我注意到一些可用的框架( navrouter
和sammy.js
)可用,但據我所知,要實現它們需要花費很多精力,尤其是如果模板中已經存在它們。
至於為什么我做這些假設的原因,有一篇文章在這里 ,這表明這是地方由於這一部分:
// app.viewmodel.js - there is a method called "addViewModel()
if (typeof (options.navigatorFactory) !== "undefined") {
navigator = options.navigatorFactory(self, dataModel);
} else {
//suggests "#"-hash navigation
navigator = function () {
window.location.hash = options.bindingMemberName;
};
}
但是在我自己的app.viewmodel.js
這些行根本沒有引用哈希:
if (typeof (options.navigatorFactory) !== "undefined") {
navigator = options.navigatorFactory(self, dataModel);
} else {
navigator = function () {
self.errors.removeAll();
self.view(viewItem);
};
}
這里在app.viewmodel.js
有對哈希的引用,但這似乎無法處理導航:
// Private operations
function cleanUpLocation() {
window.location.hash = "";
if (typeof (history.pushState) !== "undefined") {
history.pushState("", document.title, location.pathname);
}
}
function getFragment() {
if (window.location.hash.indexOf("#") === 0) {
return parseQueryString(window.location.hash.substr(1));
} else {
return {};
}
}
我的導航代碼如下所示:
<ul class="nav navbar-nav navbar-right">
<li data-bind="with: user"><a href="#" data-bind="click: manage">manage</a></li>
</ul>
導航工廠非常默認,例如:
app.addViewModel({
name: "Manage",
bindingMemberName: "manage",
factory: ManageViewModel,
navigatorFactory: function (app) {
return function (externalAccessToken, externalError) {
app.errors.removeAll();
app.view(app.Views.Manage);
if (typeof (externalAccessToken) !== "undefined" ||
typeof (externalError) !== "undefined") {
app.manage().addExternalLogin(externalAccessToken, externalError);
} else {
app.manage().load();
};
}
}
});
問題(S)
sammy.js
或navrouter
? 經過一天的奮斗,我得出以下結論:
VS2013 MVC 5 SPA template
似乎沒有#
導航。 我設法使其正常工作,因此在這里我將總結實現方法。
雖然pagerjs
,保羅Manzotti建議,做工作得很好,我已經選擇使用sammy.js
執行導航。 其他導航框架也應該工作。
因此,第一步是從nuget
獲取它:
安裝軟件包sammy.js
安裝sammy.js
之后,我們需要更改默認的VS2013 MVC 5 SPA template
的javascript
文件。 我總結一下:
首先啟用sammy.js
。 有各種各樣的代碼放置位置選項,但是由於我想在整個應用程序中使用它,因此將其放置在: ~/Scripts/app/_run.js
如下所示:
//_run.js
$(function () {
app.initialize();
// Activate Knockout
ko.validation.init({ grouping: { observable: false } });
ko.applyBindings(app);
//provides basic '#' navigation
//run this function after the initialization of the
//default knockout code.
Sammy(function () {
//"#:view" is the parameter's name of the data after the hash tag
//it is stored in "this.params.view"
this.get('#:view', function () {
//call the navigation functions
//these are created in the default knockout initiallization
app["_navigateTo" + this.params.view]();
});
}).run("#Home");//Specify the starting page of your application
});
接下來,我希望#
導航“開箱即用”。 一個關鍵部分是在導航#
參數添加到url
所以,我需要在掛鈎navigateTo
功能。 ~/Scripts/app/app.viewmodel.js
有一種方法:
更改:
//app.viewmodel.js
...
// Add navigation member to AppViewModel (for example, app.NavigateToHome());
self["navigateTo" + options.name] = navigator;
至:
//app.viewmodel.js
...
// Add navigation member to AppViewModel (for example, app.NavigateToHome());
// Override default routing to just set the hash
self["navigateTo" + options.name] = function() {
window.location.hash = options.name;
};
//this one is used by sammy to perform actual default routing
self["_navigateTo" + options.name] = function() {
navigator();
};
最后的細節必須確定,也就是說,當用戶刷新頁面時,默認路由將轉到#Home
。 這是由於~/Scripts/app/app.viewmodel.js
的以下代碼~/Scripts/app/app.viewmodel.js
:
//app.viewmodel.js
...
self.navigateToLoggedIn = function (userName, accessToken, persistent) {
self.errors.removeAll();
if (accessToken) {
dataModel.setAccessToken(accessToken, persistent)
}
self.user(new UserInfoViewModel(self, userName, dataModel));
//this line only routes to "#Home" when navigation
//after the login... or register, or something else
if (window.location.hash === "#Login" || window.location.hash === "#Register")
self.navigateToHome();
};
因此,在此代碼中添加適當的if
語句,並且#
到位。
用來訪問管理頁面的正確URL為:
http://localhost:18759/#Manage
我必須說,我還沒來得及給它一個適當的審查(在#
URL編碼可能會被用於其他地方,並可能導致沖突)。 如果發現一些問題,我將更新此帖子。
另一點:當然,可以采用多種替代方法來連接路由。 我之所以選擇這些步驟,是因為它們適用於我正在處理的情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.