gpt4 book ai didi

knockout.js - 了解 VS2013 MVC 5 SPA 模板

转载 作者:行者123 更新时间:2023-12-02 00:46:25 31 4
gpt4 key购买 nike

我已经开始使用 Visual Studio 2013 附带的 MVC 5 单页应用程序模板。我非常熟悉 Knockout.js,尽管我不熟悉 Sammy.js 我一直在阅读它,它看起来并不那么复杂。

我似乎无法理解 MVC 5 SPA 模板如何结合这些技术,或者 Visual Studio 团队对该模板的想法是什么;该模板除其他外还提供了一个 home.viewModel.js 文件,该文件应该作为起点,但我似乎无法理解如何使用 Sammy 添加更多 View .js 路线。如果他们提供了第二个部分 View 和 View 模型就好了。

我的问题

所以,长话短说,我真正的问题是,

  1. 如何以模仿提供的 home.viewmodel.js 的方式显示链接到路由 #users 的部分 View ,以便我可以导航从#home 来回#usersSammy.js 路由定义在 users.viewModel.js 中是什么样子?
  2. 我需要执行任何特殊操作才能启用浏览器后退按钮吗?还是只要我正确定义了路线,它就会立即起作用?
  3. 是我觉得还是这个模板感觉像是一个半生不熟的示例?

以下代码仅供额外引用/上下文,但对于回答问题可能没有必要。

<小时/>

一些背景

假设我创建了一个分部 View _Users.cshtml,由 UserController 提供服务,它是一个 MVC Controller ,而不是 WebAPI > Controller ,并且我想通过 Sammy.js 路由显示该部分 View ,为此我创建了一个 users.viewModel.js。现在...

提供的Index.cshtml View 如下所示:

@section SPAViews {
@Html.Partial("_Home")
}
@section Scripts{
@Scripts.Render("~/bundles/knockout")
@Scripts.Render("~/bundles/app")
}

我认为这意味着应用程序“shell”页面,其中将加载其余部分 View 以替换 _Home 部分的内容。问题在于,在 home.viewmodel.js 上,Sammy 路由在初始化时没有传入将保存内容的元素的选择器,如下所示

Sammy(function () {
this.get('#home', function () {
// more code here
}

而不是,例如

Sammy("#content", function () {
this.get('#home', function () {
// more code here
}

我是否应该从一开始就将 _Users 部分放在 _Home 旁边,以便 Index View 看起来像这样?

@section SPAViews {
@Html.Partial("_Home")
@Html.Partial("_Users")
}
@section Scripts{
@Scripts.Render("~/bundles/knockout")
@Scripts.Render("~/bundles/app")
}

这当然会同时显示两个 View ,这不是我们想要的。

我的users.viewmodel.js看起来像这样:

function UsersViewModel(app, dataModel) {
var self = this;

Sammy(function () {
this.get('#users', function () {
// the following line only makes sense if _Users is not
// called from Index.cshtml
//this.load(app.dataModel.shoppingCart).swap();
});
});

return self;
}

app.addViewModel({
name: "Users",
bindingMemberName: "users",
factory: UsersViewModel
});

我尝试使用 Sammy.js swap 方法,但由于我的 _Users View 是部分 View ,并且 Sammy 未设置为作用于特定元素,整个页面被替换...并且浏览器的后退按钮似乎不起作用。

很抱歉文字太多,如果这是一个非常微不足道的问题。令我困扰的是,即使在阅读了文档之后,我似乎也无法自己解决这个问题。

最佳答案

我自己偶然发现了这个问题,我设法应用自己的小“技巧”​​来解决这个问题。

在将“旧”模板与新模板进行比较时,我注意到 Sammy.js 更加嵌入到模板中。尽管这是一件好事,但用于显示 View 的原始开箱即用的 with 绑定(bind)已被破坏。

要应用修复,首先需要了解 knockout with绑定(bind)。在默认的 home View 中,有

<!-- ko with: home-->

仅当成员 home 存在时才应确保 home View 可见性的语句。在这种情况下,全名将是 app.home

如果我们检查这个成员名称,我们会看到它是一个计算成员,定义如下(app.viewmodel.js):

// Add binding member to AppViewModel (for example, app.home);
self[options.bindingMemberName] = ko.computed(function () {
if (!dataModel.getAccessToken()) {
//omitted for clearity
if (fragment.access_token) {
//omitted for clearity
} else {
//omitted for clearity
}
}

return self.Views[options.name];
});

如您所见,它始终从 Views 集合中返回完整初始化的 View 。

如果我们将其与旧模板进行比较,我们可以看到这里的变化:

// Add binding member to AppViewModel (for example, app.home);
self[options.bindingMemberName] = ko.computed(function () {
if (self.view() !== viewItem) {
return null;
}

return new options.factory(self, dataModel);
});

如果当前 View 不是目标viewItem,则返回 null。这对于 knockout 的 with 绑定(bind)至关重要。

对这两个模板的进一步检查表明与 sammy.js 的集成更好。它的关键部分在于 View 模型(home.viewmodel.js):

Sammy(function () {
this.get('#home', function () {
});
this.get('/', function () { this.app.runRoute('get', '#home') });
});

由于 sammy.js 正在处理导航,因此前面提到的封装在 app.view() 中的 viewItem 未设置。这对于 knockout 结契约(Contract)样至关重要。

因此,我建议的修复如下:

app.viewmodel.js

// Add binding member to AppViewModel (for example, app.home);
self[options.bindingMemberName] = ko.computed(function () {
if (!dataModel.getAccessToken()) {
//omitted for clearity
if (fragment.access_token) {
//omitted for clearity
} else {
//omitted for clearity
}
}

///change start here
if (self.view() !== viewItem) {
return null;
}

return self.Views[options.name];
});

在每个自定义 View 模型中:

home.viewmodel.js

Sammy(function () {
this.get('#home', function () {
app.view(self); //this line is added
});
this.get('/', function () { this.app.runRoute('get', '#home') });
});

免责声明:由于我刚刚启动并运行它,所以我没有时间分析任何不需要的副作用。此外,改变默认模板的核心感觉不太令人满意,因此欢迎更好的解决方案。

关于knockout.js - 了解 VS2013 MVC 5 SPA 模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25971154/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com