Передайте постоянные значения в Angular из _layout.cshtml

Итак, у меня есть постоянные переменные в _Layout.cshtml проекта ASP.Net SPA, и я хотел бы передать их, чтобы Angular имел доступ к ним.

Как я могу это сделать?

Например, вот одно значение, которое я пытаюсь передать.

var lenderValues = @Html.Action("GetLenderDropdownValues", "Dropdown");

и вот как загружается мой первый app.component.

<my-rite-ui>Loading...</my-rite-ui>

Я знаю, как сделать это в AngularJS 1.x, используя только константу и вводить эту константу, где бы это ни было необходимо, но я не смог понять это в Angular.

Любая помощь будет высоко оценена.

3 ответа

Решение

Это зависит от того, что именно вы хотите сделать, но я вижу две возможности:

  • Определить константу

Эту константу необходимо передать при импорте вашего основного модуля. В то время как это невозможно сделать на import сам. Вы можете импортировать функцию и вызывать ее с параметрами.

Вот пример основного модуля, который загружает ваше приложение:

import {bootstrap} from '...';
import {provide} from '...';
import {AppComponent} from '...';

export function main(lenderValues) {
  bootstrap(AppComponent, [
    provide('lenderValues', { useValue: lenderValues })
  ]);
}

Затем вы можете импортировать его с главной страницы HTML следующим образом:

<script>
  var lenderValues = @Html.Action("GetLenderDropdownValues", "Dropdown");
  System.import('app/main').then((module) => {
    module.main(lenderValues);
  });
</script>

Ваш lenderValues затем может быть введен во все элементы, такие как компонент:

@Component({
  (...)
})
export class SomeComponent {
  constructor(@Inject('lenderValues') lenderValues) {
  }
}
  • Определить параметр на my-rite-ui элемент

Вы можете указать параметр на этом уровне, но он не может быть оценен. Так что это немного более утомительно, так как вам нужно сериализовать его как строку с JSON.stringify, получает элемент в вашем компоненте из соответствующего ElementRef и десериализовать его, используя JSON.parse,

Затем вы можете добавить данные в качестве поставщика.

Первый ответ выше был моим любимым, если вы используете JIT-компиляцию. Мы используем JIT для разработки и AOT для развертывания. Я не мог найти хороший способ заставить первый ответ работать с AOT. Для справки я следовал поваренной книге AOT здесь... Угловая поваренная книга AOT.

Приведенный ниже подход не будет работать для рендеринга на стороне сервера, но должен быть достаточным для рендеринга на стороне клиента JIT и AOT.

1) В виде бритвы, например, _layout.cshtml, просто поместите блок скрипта и установите объект JSON в интерфейсе окна. Я поместил этот блок в тег head, но это не имеет значения. Значения ключей JSON могут быть определены любым синтаксисом бритвы.

<script type="text/javascript">
    window.appContext = {
        userName: '@("test".ToUpper())',
        isAdmin: @(1 == 1 ? "true" : "false")
    };
</script>

2) Создайте службу контекста приложения, подключите ее в соответствующем модуле и внедрите в компоненты для использования, если вам нужна помощь, просто прокомментируйте, и я предоставлю дополнительную информацию.

import { Injectable } from '@angular/core';

/*
    must match definition in SCRIPT tag that is seeded from razor
*/
interface IAppContext {
    userName: string;

    isAdmin: boolean;
}

/*
    
*/
@Injectable()
export class AppContextService implements IAppContext {

    userName: string;

    isAdmin: boolean;

    constructor() {
        var appContextBootstrap: IAppContext = (<IAppContext>(<any>window).appContext);

        this.userName = appContextBootstrap.userName;
        this.isAdmin = appContextBootstrap.isAdmin;
    }

}

3) ссылаться и использовать контекстную службу приложения во всем приложении.

import { Component } from '@angular/core';

import { AppContextService } from './appContext.service'

@Component({
    moduleId: module.id,
    selector: 'story-app',
    templateUrl: 'app.component.html'
})
export class AppComponent {
    AppConfig: any;
    constructor(private appContext: AppContextService) { }

    ngOnInit() {

        alert('hi - ' + this.appContext.userName);
    }
}

В чем проблема? Я легко получить значение от HTML-страницы, как это.

HTML

<script type="text/javascript"> var getThisValue='I want this string in component'; </script>

<html>
  <head>
    <base href="/">
    <title>Angular 2 - Tour of Heroes</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="styles.css">

    <!-- 1. Load libraries -->
     <!-- Polyfill(s) for older browsers -->
    <script src="node_modules/es6-shim/es6-shim.min.js"></script>

    <script src="node_modules/zone.js/dist/zone.js"></script>
    <script src="node_modules/reflect-metadata/Reflect.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>

    <!-- 2. Configure SystemJS -->
    <script src="systemjs.config.js"></script>
    <script>
      System.import('app').catch(function(err){ console.error(err);  });
    </script>    

    <script type="text/javascript">
      var getThisValue='I want this string in component';
    </script>
  </head>
  <!-- 3. Display the application -->
  <body>
    <my-app>Loading...</my-app>
  </body>
</html>

Вызов файла основного компонента

alert(getThisValue);

    import { bootstrap } from '@angular/platform-browser-dynamic';
    import { HTTP_PROVIDERS } from '@angular/http';
    import { AppComponent } from './app.component';
    //import { enableProdMode } from '@angular/core';

    //enableProdMode();

    bootstrap(AppComponent, [HTTP_PROVIDERS]);

    alert(getThisValue);

Это работа для меня

На то, что я заметил в вашем коде, вы должны использовать '' пометить для доступа к URL.

Замени это

var lenderValues = @Html.Action("GetLenderDropdownValues", "Dropdown");

с этим

var lenderValues = '@Html.Action("GetLenderDropdownValues", "Dropdown")';

Это самый простой вариант для доступа к значению из HTML конечно не правильно. Чтобы получить доступ к этому значению, вам нужно определить константу, как определено в Thierry Templier ответ выше.

Другие вопросы по тегам