【问题标题】:knockoutjs mvc button action change per viewModel每个viewModel的knockoutjs mvc按钮操作更改
【发布时间】:2014-11-10 15:05:52
【问题描述】:

我目前正在将 knockoutjs 与我的一个 MVC 应用程序一起使用。 布局模板如下所示:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
</head>
<body>
    <div class="container-fluid head-content">
        <div class="row">
            <div class="col-xs-6">
                <img class="img-responsive" src="~/Images/logo.jpg" />
            </div>
            <div class="col-xs-3">
                <a class="block" href="#" style="display: none" data-bind="visible: showBack, click: goBack">
                    <div class="block-text">
                        <h4>Back</h4>
                    </div>
                </a>
            </div>
            <div class="col-xs-3">
                <a class="block" href="#" style="display: none" data-bind="visible: showHome, click: navigateToHome">
                    <div class="block-text">
                        <h4>Home</h4>
                    </div>
                </a>
            </div>
        </div>
    </div>

    <div class="container-fluid body-content">
        @RenderBody()
    </div>

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)
</body>

</html>

我的 Index 部分看起来像这样:

@Html.Partial("_Login")
@Html.Partial("_Home")
@Html.Partial("_CutLengths")
@Html.Partial("_MoveStock")

@section scripts {
    @Scripts.Render("~/bundles/knockout")
    @Scripts.Render("~/bundles/app")
}

我的问题是,根据我所在的页面,我想使用后退按钮转到另一个页面。例如,如果我在 cutLengths 上,我希望后退按钮带我 home

我的 app.viewmodel.js 有一个如下所示的方法:

// Other operations
self.addViewModel = function (options) {
    var viewItem = {},
        navigator;

    // Add view to AppViewModel.Views enum (for example, app.Views.Home).
    self.Views[options.name] = viewItem;

    // 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);
    });

    if (typeof (options.navigatorFactory) !== "undefined") {
        navigator = options.navigatorFactory(self, dataModel);
    } else {
        navigator = function () {
            self.view(viewItem);
        };
    }

    // Add navigation member to AppViewModel (for example, app.NavigateToHome());
    self["navigateTo" + options.name] = navigator;
};

我想做的是从 ViewModel 传递一个字符串,我目前正在查看该字符串,当按下后退按钮时会知道将我引导到右侧 ViewModel .

可以这样做吗?

我希望我已经解释清楚了,如果我没有请询问,我会更加努力:D

【问题讨论】:

    标签: c# asp.net-mvc mvvm knockout.js


    【解决方案1】:

    您可以使用 ViewData 或 ViewBag 将数据从控制器传递到视图。因此,一种选择是在 ViewBag 中为当前视图模型和先前的视图模型添加一些动态属性。

    ViewData 是使用字符串作为键来存储和检索对象的字典。

    ViewBag 使用 C# 4 中引入的动态特性。它允许对象动态添加属性。我会用它来传递你的视图模型状态。

    都不提供编译时检查,这是它们的美妙之处,你可以添加任何你想要的东西。话虽如此,在 ViewBag 和 ViewData 上使用强类型视图模型始终是一个好习惯。

    如果您宁愿在视图模型中放置一些东西,而不是向 ViewBag 添加属性,而不是在每个视图模型中添加另一个名为 PreviousViewModel 的属性并在您使用模型时填充它。

    使用 ViewBag 或 ViewData 的示例

    ViewData["LastViewModel"] = "CutLengths";
    ViewBag.LastViewModel = "CutLengths";
    

    在 Views 中访问您的 ViewBag 没问题,它们具有全局范围。 ViewBag 就像一个全局变量,你可以附加任何东西——所以我会明智地使用它们——也许某种类型的单例应用程序管理器会是更好的设计。

    希望对你有帮助

    【讨论】:

    • 嗨,我觉得你也有点困惑 :) 这不是我说的 MVC,这是淘汰赛 js :(
    • 哦,开枪。我的错。当我做出这个答案的时候已经很晚了。哈哈对不起。
    【解决方案2】:

    我现在已经解决了这个问题。首先我改变了我的 HTML

    <div class="col-xs-3">
        <a class="block btn-back" href="#" data-bind="visible: showBack, click: goBack"></a>
    </div>
    <div class="col-xs-3">
        <a class="block btn-home" href="#/home" data-bind="visible: showHome"></a>
    </div>
    

    然后我编辑了我的 app.viewmodel.js 文件并添加了这些

    // Data
    self.back = ko.observable(null);
    
    
    // UI state
    self.showBack = ko.observable(true);
    self.showHome = ko.observable(true);
    self.goBack = function () {
        if (self.back()) {
            window.location.href = self.back();
        } else {
            window.history.back();
        }
    
        self.back(null); // Reset
    };
    self.setBackUrl = function (url) {
        self.back(url);
    }
    

    然后在我的 addViewModel 导航功能上,我添加了这个:

    if (typeof (options.navigatorFactory) !== "undefined") {
        navigator = options.navigatorFactory(self, dataModel);
    } else {
        navigator = function () { // This is our navigator function which sets the current view
            self.showBack(true);
            self.showHome(true);
            self.error(null); // Reset errors
    
            self.view(viewItem);
        };
    }
    

    然后在我的其他视图模型中,我只需像这样调用 setBackUrl

    app.setBackUrl("#/cut-lengths");
    

    如果我想隐藏我的按钮,那也很容易。我只是像这样在 viewModel 上创建一个 navigatorFactory

    app.addViewModel({
        name: "Home",
        bindingMemberName: "home",
        factory: HomeViewModel,
        navigatorFactory: function (app) {
            return function () {
                app.showBack(false);
                app.showHome(false);
                app.error(null);
    
                app.view(app.Views.Home);
            }
        }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-02
      • 1970-01-01
      • 1970-01-01
      • 2017-03-17
      • 2019-01-19
      • 2014-12-10
      相关资源
      最近更新 更多