在 Angular 模板中使用 http cookie 值

Use http cookie value in an Angular template

我 angular 在我的一个 ASP.NET MVC 应用程序中工作。我正在使用两个 html 模板和 Angular 路由。一个是来自数据库的当前收藏夹列表,从我的 Web API 序列化到 json 并被 angular 用来列出数据库中的那些项目。

第二个 html 模板是用于添加新收藏夹的表单。当包含我的 angular 代码的整个页面加载时,它有一个名为 currentSearch 的 cookie,它保存用户执行的最后一个搜索参数的值。

我想将此值注入到我的 angular html 模板 (newFavoriteView.html) 中,作为隐藏输入的值,其名称和 ID 为 searchString

我曾尝试使用 jQuery,但遇到了问题,而且我更愿意在 angular 中执行此操作,并以某种方式将值传递给我的模板或在视图中执行工作(模板)。但是,我知道后者是不好的形式。下面是我认为对于理解我在做什么的人来说很重要的代码。

Index.cshtml(我的 ASP.NET 视图)

@{
    ViewBag.Title = "Render Search";
    ViewBag.InitModule = "renderIndex";
}
    <div class="medium-12 column">
        <div data-ng-view=""></div>
    </div>
@section ngScripts {
    <script src="~/ng-modules/render-index.js"></script>
}

在 MVC 控制器中设置 cookie

    private void LastSearch()
    {
        string lastSearch = null;
        if (Request.Url != null)
        {
            var currentSearch = Request.Url.LocalPath + "?" + 
                                    Request.QueryString;

            if (Request.Cookies["currentSearch"] != null)
            {
                lastSearch = Request.Cookies["currentSearch"].Value;
                ViewBag.LastSearch = lastSearch;
            }

            if (lastSearch != currentSearch)
            {
                var current = new HttpCookie("currentSearch", currentSearch){ 
                                   Expires = DateTime.Now.AddDays(1) };
                Response.Cookies.Set(current);

                var previous = new HttpCookie("lastSearch", lastSearch) { 
                                   Expires = DateTime.Now.AddDays(1) };
                Response.Cookies.Set(previous);
            }
        }
    }

render-index.js

angular
    .module("renderIndex", ["ngRoute"])
    .config(config)
    .controller("favoritesController", favoritesController)
    .controller("newFavoriteController", newFavoriteController);

function config($routeProvider) {
    $routeProvider
        .when("/", {
            templateUrl: "/ng-templates/favoritesView.html",
            controller: "favoritesController",
            controllerAs: "vm"
        })
        .when("/newsearch", {
            templateUrl: "/ng-templates/newFavoriteView.html",
            controller: "newFavoriteController",
            controllerAs: "vm"
        })
        .otherwise({ redirectTo: "/" });
};

function favoritesController($http) {
    var vm = this;
    vm.searches = [];
    vm.isBusy = true;

    $http.get("/api/favorites")
        .success(function (result) {
            vm.searches = result;
        })
        .error(function () {
            alert('error/failed');
        })
        .then(function () {
            vm.isBusy = false;
        });
};

function newFavoriteController($http, $window) {
    var vm = this;
    vm.newFavorite = {};
    vm.save = function () {
        $http.post("/api/favorites", vm.newFavorite)
            .success(function (result) {
                var newFavorite = result.data;
                //TODO: merge with existing topics
                alert("Thanks for your post");
            })
            .error(function () {
                alert("Your broken, go fix yourself!");
            })
            .then(function () {
                $window.location = "#/";
            });
    };
};

favoritesView.html

<div class="container">
    <h3>New Favorite</h3>
    <form name="newFavoriteForm" ng-submit="vm.save()">
    <fieldset>
      <div class="row">
        <div class="medium-12 column">
          <input name="searchString" id="searchString" type="hidden" 
                 ng-model="vm.newFavorite.searchString"/>
            <label for="title">Name</label><br />
              <input name="title" type="text" 
                     ng-model="vm.newFavorite.name"/>
                <label for="title">Description</label><br />
                <textarea name="body" rows="5" cols="30" 
                          ng-model="vm.newTopic.description"></textarea>
              </div>
              <div class="medium-12 column">
                <input type="submit" class="tiny button radius" value="Save"/> | 
                <a href="/" class="tiny button radius">Cancel</a>
              </div>
          </div>
      </fieldset>
  </form>
</div>

我目前的尝试是在 Angular 加载后在页面末尾使用 jQuery 并获取 cookie 并将其填充到隐藏值中。但我无法让它发挥作用。我还考虑过将值设置为 javascript 变量(在我的 c# 页面中),然后以某种方式在 angular 中使用该变量。我这样做的方式正确吗?

还是应该在angular控制器中处理?...

我是 angular 的新手,Angular Scope 和一些无知妨碍了我。如果需要任何其他信息,我可以提供,如果您能帮助或指导我正确的方向,谢谢。

抱歉,如果我误解或过度简化了,但是......假设 JavaScript 可以读取这个 cookie 值,你可以让你的控制器读取它并将它分配给 $scope变量?

如果JavaScript无法读取值,那么您可以让ASP将值写入JavaScript内联脚本标签。不过这感觉更恶心。

更新 以显示控制器为例。

假设您的 HTML 看起来像这样:

<div ng-controller="MyController as controller">
  <!-- other HTML goes here -->
  <input name="searchString" id="searchString" type="hidden" ng-model="controller.data.currentSearch"/>

那么你的控制器可能看起来像这样:

app.controller('MyController', function ($scope, $cookies) {
  $scope.data = {
    currentSearch: $cookies.currentSearch
  };
  // Note that the model is nested in a 'data' object to ensure that
  // any ngIf (or similar) directives in your HTML pass by reference
  // instead of value (so 2-way binding works).
});

您可以使用 JavaScript 读取 cookie 值,将其设置为 $scope 对象的 属性 并在模板上访问它。

//Inside your controllers
function favoritesController($http, $scope) {
    //Get the cookie value using Js
    var cookie = document.cookie; //the value is returned as a semi-colon separated key-value string, so split the string and get the important value

    //Say the cookie string returned is 'currentSearch=AngularJS'
    //Split the string and extract the cookie value

    cookie = cookie.split("="); //I am assuming there's only one cookie set

    //make the cookie available on $scope, can be accessed in templates now
    $scope.searchString = cookie[1];
}

额外说明 在 AngularJS 中,范围是应用程序控制器和视图之间的粘合剂。控制器和视图共享这个作用域对象。范围就像您的应用程序的模型。由于控制器和视图共享同一个作用域对象,它可以用来在两者之间进行通信。作用域可以包含视图中 运行 的数据和函数。请注意,每个控制器都有自己的范围。如果要访问它,必须将 $scope 对象注入到控制器中。

例如:

//inject $http and $scope so you can use them in the controller
function favoritesController($http, $scope) {

可以在视图上访问作用域中存储的任何内容,也可以从视图中设置作用域 属性 的值。范围对象对于 Angular 的双向数据绑定很重要。