【问题标题】:What is the best way to set AngularJS $provide.constant values from a C# MVC Model?从 C# MVC 模型中设置 AngularJS $provide.constant 值的最佳方法是什么?
【发布时间】:2014-09-05 20:23:44
【问题描述】:

我有一个带有 .NET MVC/WebAPI 后端的 AngularJS 应用程序。我有一个 MVC 操作来提供加载我的 AngularJS 应用程序的主 HTML 页面。此 MVC 操作从 Web.config 和数据库加载多个应用程序设置,并将它们作为模型返回到视图。我正在寻找一种在我的 AngularJS .config 方法中将这些 MVC Model 值设置为 $provide.constant 值的好方法。

MVC 控制器方法:

public ActionResult Index() {
    var model = new IndexViewModel {
        Uri1 = GetUri1(),
        Uri2 = GetUri2()
        //...etc
    };
    return View(model);
}

我的 MVC _Layout.cshtml:

@model IndexViewModel
<!doctype html>
<html data-ng-app='myApp'>
<head>
    @Styles.Render("~/content/css")
    <script type='text/javascript'>
        @if (Model != null)    //May be null on error page
        {
            <text>
                var modelExists = true;
                var uri1 = '@Model.Uri1';
                var uri2 = '@Model.Uri2';
            </text>
        }
        else
        {
            <text>
                var modelExists = false;
            </text>
        }
    </script>
</head>
<body>
    <!-- Body omitted -->
    @Scripts.Render("~/bundles/angular", "~/bundles/app") //Loads angular library and my application
</body>

app.js:

"use strict";
angular.module('myApp', [])
    .config(['$provide' '$window', function ($provide, $window) {
        if ($window.modelExists){
            $provide.constant('const_Uri1', $window.uri1);
            $provide.constant('const_URi2', $window.uri2);
        }            
    }]);

这是我的代码的一个大大简化的版本,但我认为它说明了我的担忧。有没有我忽略的更好或标准的方法来做到这一点?我不喜欢_Layout.cshtml 中的代码,因为我有更多的配置值。

【问题讨论】:

  • 而不是单个变量,而是传递一个带有这些变量作为属性的对象。那么你所需要的只是你的应用程序中的对象引用
  • 您的意思是将常量设置为具有属性的对象吗?据我所知,AngularJS $provide.constant 值不能有属性。
  • 我的意思是var appConfig={ modelExists:true, ur1: '@Model.Uri1'..}。常量也可以是一个对象,但由于全局命名空间,您也可以在任何地方访问该数据
  • 我可能错了,常量可以是对象,但还有许多其他方法可以将我建议的配置对象传递给应用程序...value,通过服务,创建提供程序等
  • 对,我现在一直通过 $window.uri1 访问变量,但我不喜欢这样,因为它污染了窗口空间。我同意您将 appConfig 设为对象的建议肯定会使窗口更清洁,但我希望有更好的方法。

标签: c# asp.net-mvc angularjs asp.net-web-api


【解决方案1】:

如果你有一堆配置值并且你不介意额外的网络调用,一种方法是创建一个 MVC 视图,将设置作为 Angular 常量返回...

using System.Web.Script.Serialization;

// ...

public ActionResult Settings(string angularModuleName = "myApp")
{
    var settings = new 
    {
        uri1 = GetUri1(),
        uri2 = GetUri1()
        // ...
    };

    var serializer = new JavaScriptSerializer();
    var json = serializer.Serialize(settings);

    var settingsVm = new SettingsViewModel
    {
        SettingsJson = json,
        AngularModuleName = angularModuleName
    };

    Response.ContentType = "text/javascript";
    return View(settingsVm);
}

在 Razor 视图中...

@model MyApp.SettingsViewModel
@{
    Layout = null;
}

(function (app) {
    app.constant('settings', @Html.Raw(Model.SettingsJson));
})(angular.module('@Model.AngularModuleName'));

在需要文件的页面中,只需添加一个脚本标签,将常量引入...

@Scripts.Render("~/bundles/angular", "~/bundles/app") //Loads angular library and my application
<script src="/home/settings?appname=foo"></scripts>

这将返回脚本...

(function (app) {
    app.constant('settings', {
        "uri1": "https://uri1",
        "uri2": "https://uri2"
    });
})(angular.module('foo'));

现在您可以在 Angular 代码中的任何位置注入 settings 服务。没有任何东西泄漏到全局范围内。

您也可以使用这种技术将设置直接注入特定的 HTML 视图,但我通常更喜欢将其拆分,以便仅在需要时包含它。

【讨论】:

  • 我非常喜欢这个想法,我正在尝试,但是我没有看到 JavaScriptSerializer 类。我什至没有看到要添加的System.Web.Scripts 引用。这是从哪里来的?
  • 它是System.Web.Script,我相信它应该在System.Web.Extensions。根据 Web 项目模板,该 dll 可能已被引用。另外,如果你已经在使用 JSON.NET,你可以使用它来序列化。
  • 我只是用 JSON.NET 来序列化它。谢谢 Anthony,我真的很喜欢这个解决方案,它极大地帮助我清理了我的应用程序。
  • 正是我正在寻找的东西,并且出于完全相同的原因。 +1
  • 太棒了!从那以后,我在博客上对此进行了更详细的介绍,并开始使用相同的技术进行客户端本地化(为角度序列化 resx 文件)...anthonychu.ca/post/how-to-pass-webconfig-settings-to-angularjs
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-23
  • 2010-11-13
  • 2014-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多