Как передать данные из 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);
}
}