Как передать данные из asp.NET MVC в Angular2

Каков наилучший способ передачи данных с ASP.NET MVC-контроллера на компонент Angular 2.0. Например, мы используем модель ASP.NET MVC и хотели бы отправить ее версию JSON в Angular, поэтому мы можем использовать ее в Angular.

В настоящий момент контроллер обслуживает представление, мы можем уже нажимать некоторые данные на Angular2 (модель). Поэтому дополнительный вызов AJAX для извлечения этих данных не требуется.

Однако я изо всех сил пытаюсь "ввести" его в компонент Angular. Как ты делаешь это? Любые хорошие ссылки для этого? Как вы, возможно, заметили, я новичок в Angular2.

Мой index.cshtml выглядит так.

<div class="container">
<div>
    <h1>Welcome to the Angular 2 components!</h1>
</div>
<div class="row">
    <MyAngular2Component>
        <div class="alert alert-info" role="alert">
            <h3>Loading...</h3>
        </div>
    </MyAngular2Component>
</div>
</div>

С уважением,

Rob

Ответы

Ответ 1

Лучший способ, которым я нашел передать данные из MVC (или любой страницы хостинга/запуска), - это указать данные как атрибут на загрузочном компоненте и использовать ElementRef, чтобы получить значение напрямую.

Ниже приведен пример MVC, полученный из этого ответа, в котором говорится, что использовать @Input для компонентов на уровне корня невозможно.

Пример:

//index.cshtml
<my-app username="@ViewBag.UserName">
    <i class="fa fa-circle-o-notch fa-spin"></i>Loading...
</my-app>


//app.component.ts
import {Component, Input, ElementRef} from '@angular/core';

@Component({
    selector: 'my-app',
    template: '<div> username: <span>{{username}}</span> </div>'
})
export class AppComponent {
    constructor(private elementRef: ElementRef) {}

    username: string = this.elementRef.nativeElement.getAttribute('username')
}

Если вы хотите получить более сложные данные, которые не подходят для атрибута, вы можете использовать тот же метод, просто поместите данные в элемент HTML <input type='hidden'/> или скрытый элемент <code> и используйте простой JS для получить значение.

myJson: string = document.getElementById("myJson").value

Предупреждение: Доступ к DOM непосредственно из приложения с привязкой к данным, такого как Angular, разбивает шаблон привязки данных и должен использоваться с осторожностью.

Ответ 2

Возможно, вам захочется найти похожие вопросы, относящиеся к AngularJS, а не Angular 2, поскольку основной смысл вещи остается тем же:

  • вы хотите, чтобы ваш серверный механизм Razor отображал какой-то вид (т.е. непосредственно HTML или JS).
  • это представление содержит шаблон JS, где часть содержимого заполняется из экземпляра модели сервера или любых данных сервера (например, ресурса, словаря и т.д.).
  • чтобы правильно заполнить переменную JS из Razor, серверные данные С# должны быть правильно сериализованы в формате JSON

В этот пост от Marius Schulz вы можете видеть, как он сериализует данные и использует это для заполнения шаблона AngularJS value:

<script>
  angular.module("hobbitModule").value("companionship", @Html.Raw(Model));
</script>

Нечто подобное может быть сделано для ввода некоторых данных, например. в window.myNamespace.myServerData, а затем Angular2 bootstrap, что значение среди других поставщиков.

В этот пост от Roel van Lisdonk, аналогичный подход используется, опять же, для заполнения шаблона на основе AngularJS, с этим ng-init директива:

<div ng-controller="main"
     ng-init="resources={ textFromResource: '@WebApplication1.Properties.Resources.TextFromResource'}">
  <h1>{{ title }}</h1>
  {{ resources.textFromResource }}
</div>

Как указывает первый пост, есть что подумать (вставка здесь):

Предупреждение: метод, который я собираюсь использовать, вероятно, не подходит для больших объемов данных. Поскольку данные JavaScript встроены в ответ HTML, он отправляется по сети каждый раз, когда вы запрашиваете эту страницу.

Кроме того, если данные специфичны для аутентифицированного пользователя, ответ не может быть кэширован и доставлен другим пользователям. Помните об этом, рассматривая возможность загрузки ваших Angular приложений с данными .NET таким образом.

Вторая часть может быть меньше проблемы, если ваша обслуживаемая страница уже является динамической серверной, т.е. если в ней уже есть биты, заполненные вне серверных данных.

НТН

Ответ 3

Вы можете использовать функцию Input, открытую @angular/core, у меня есть, например, компонент Angular 2 для отображения информационных сообщений пользователю приложения

Мой шаблон HTML принимает свойство Angular 2 Message

<div class="alert alert-info col-lg-10 col-lg-offset-1 col-md-10 col-md-offset-1 col-sm-10 col-sm-offset-1 col-xs-10 col-xs-offset-1">
    <i class="fa fa-info-circle"></i> {{ Message }}
</div>

Свойство Message передается как вход в мой компонент Angular 2 с именем informationmessage.component.ts, например

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

@Component({
    selector: 'informationmessage',
    templateUrl: '../Templates/informationmessage.component.html'
})
export class InformationMessageComponent {
    @Input() Message: string;
}

Затем я передаю данные на мой InformationMessageComponent, используя привязку свойств на странице HTML, например.

<informationmessage [Message]="InformationMessage"></informationmessage>

Вы можете заменить InformationMessage в приведенном выше примере данными, которые вы получаете от вашего контроллера MVC, например

<informationmessage [Message]="@Model.InformationMessage"></informationmessage>

Обратите внимание: Я не тестировал этот сценарий, но нет технических причин, по которым он не работает, в конце дня вы просто привязываете значение к свойству Angular 2.

Ответ 4

Вам нужно сначала связать свои службы и контроллеры в отдельных файлах модулей и загрузить службы перед контроллерами. Например:

dist
|--services.js
|--controllers.js

Затем вам нужно загрузить JavaScript-код служб через результат JavaScript ASP.NET MVC, здесь вам нужно ввести свои данные для запуска.

public class ScriptController: Controller
{
  public ActionResult GetServices(){
   string file= File.ReadAllText(Server.MapPath("~dist/services.js"));
   //modify the file to inject data or 
   var result = new JavaScriptResult();         
   result.Script = file;
   return result;     
}

Затем в index.html загрузите скрипты следующим образом

<script src="/script/getservices"></script>
<script src="/dist/controller.js"></script>

Таким образом вы можете вводить данные в код angular во время загрузки. Однако даже это влияет на производительность из-за времени, затрачиваемого на получение представления, компиляцию представления и привязки данных к представлению. Для начальной загрузки производительность может быть улучшена, если вы используете визуализацию на стороне сервера.

Ответ 5

Я нашел гораздо более простое решение. Не пытайтесь получить атрибут из конструктора! Вместо этого используйте ngOnInit() hook. Имущество будет доступно, если оно было украшено @Input(). Похоже, что к тому времени, когда вызывается конструктор, он недоступен.

Компонент HTML:

<MyComponent [CustomAttribute]="hello"></MyComponent>

Компонент TS:

export class MyComponentComponent {
    @Input()
    public CustomAttribute: string;

    constructor() {}

    ngOnInit() {
        console.log("Got it! " + this.CustomAttribute);
    }
}