从C#MVC模型设置AngularJS $ provide.constant值的最佳方法是什么?

Ada*_*lin 4 c# asp.net-mvc asp.net-web-api angularjs

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

MVC控制器方法:

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

我的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>
Run Code Online (Sandbox Code Playgroud)

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);
        }            
    }]);
Run Code Online (Sandbox Code Playgroud)

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

Ant*_*Chu 7

如果你有一堆配置值的和你不介意额外的网络电话,要做到这一点的一种方式是创建作为一个角度不变返回设置的MVC视图...

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);
}
Run Code Online (Sandbox Code Playgroud)

在Razor视图中......

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

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

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

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

这将返回脚本...

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

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

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

  • 真棒!我已经在稍微更详细的博客上写了这篇文章,并开始使用相同的技术进行客户端本地化(为角度序列化resx文件)... http://anthonychu.ca/post/how-to-pass-webconfig-设置到angularjs (2认同)