2017-01-04 5 views
6

나는 각도 2 응용 프로그램과 함께 asp.net mvc를 통합하려고합니다. 나는 이것이 이상적은 아니지만, 기존의 Mvc 기능 (큰 레거시 앱이라고 생각할 수있는)을 새로운 Angular 2 spa에 통합하라는 요청을 받고 있습니다. 내가 할 수 있도록하고 싶습니다 무엇각도 2로 asp.net MVC 뷰를 렌더링하는 방법?

<side-bar></side-bar> 
<action-bar></action-bar> 

@{ 
    Html.RenderPartial("_SuperLegacyPartialView"); 
} 

나는 어떤 방식을 찾기 위해 사투를 벌인거야 ... 거기에 각 구성 요소뿐만 아니라, 순수 MVC 물건이있는 cshtml보기가있다 이 작업을 수행. 이 블로그 게시물은 유망 해 보였습니다 - http://www.centare.com/tutorial-angular2-mvc-6-asp-net-5/. 그것은 AsyncRoute뿐 아니라 Mvc에서 렌더링 한 경로를 가리키는 templateUrl 값을 사용했지만 Angular 2에서는 더 이상 작동하지 않습니다.이 게시물은 유망한 것으로 보였습니다 ( http://gbataille.github.io/2016/02/16/Angular2-Webpack-AsyncRoute.html).하지만 AsyncRoute도 사용됩니다.

각도 1에서 매우 쉽게 사용했습니다. 우리는 면도기 뷰로 수동으로 부트 스트랩하거나 부분 뷰를 구성 요소/지시문의 templateUrl로 렌더링했습니다. Webpack을 사용하는 최신 Angular 2에서이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

답변

9

나는 그 때 나의 필요를 만족시키는 해결책을 찾았다. 저는 WebPack에서 angular-cli를 사용하고 있으며, 이것이 나의 필요에 부합했습니다. "templateUrl : '/ Template/Index'"를 사용하는 모든 예제를 이해하지 못합니다. 여기서 경로는 MVC 뷰의 경로입니다. WebPack이 생성하는 번들 뷰 중 하나에서 경로를 찾을 수 없으므로 간단히 작동하지 않습니다. 어쩌면 그 사람들은 angular-cli와 WebPack을 사용하지 않을 수도 있습니다.

이 stackoverflow 대답 - How can I use/create dynamic template to compile dynamic Component with Angular 2.0? 매우 다음 지시문을 만드는 데 도움이되었습니다. 이 지시문은 mvc 부분 뷰의 출력을 가져 와서 컴파일합니다. 그것은 면도기/서버 논리가 일어나도록 허용하고 일부 각도도 컴파일됩니다. 실제로이 MVC 부분 안에 다른 구성 요소를 포함시키는 것은 문제가있었습니다. 그 일을하게되면, 내가 한 일을 알려주십시오. 필자의 경우에는 서버 렌더링을 수행하고 Angular 2 스파에서 원했던 위치에 정확히 배치해야했습니다.

MvcPartialDirective

import { 
    Component, 
    Directive, 
    NgModule, 
    Input, 
    ViewContainerRef, 
    Compiler, 
    ComponentFactory, 
    ModuleWithComponentFactories, 
    ComponentRef, 
    ReflectiveInjector, OnInit, OnDestroy 
} from '@angular/core'; 

import { RouterModule } from '@angular/router'; 
import { CommonModule } from '@angular/common'; 
import {Http} from "@angular/http"; 
import 'rxjs/add/operator/map'; 

export function createComponentFactory(compiler: Compiler, metadata: Component): Promise<ComponentFactory<any>> { 
    const cmpClass = class DynamicComponent {}; 
    const decoratedCmp = Component(metadata)(cmpClass); 

    @NgModule({ imports: [CommonModule, RouterModule], declarations: [decoratedCmp] }) 
    class DynamicHtmlModule { } 

    return compiler.compileModuleAndAllComponentsAsync(DynamicHtmlModule) 
    .then((moduleWithComponentFactory: ModuleWithComponentFactories<any>) => { 
     return moduleWithComponentFactory.componentFactories.find(x => x.componentType === decoratedCmp); 
    }); 
} 

@Directive({ selector: 'mvc-partial' }) 
export class MvcPartialDirective implements OnInit, OnDestroy { 
    html: string = '<p></p>'; 
    @Input() url: string; 
    cmpRef: ComponentRef<any>; 

    constructor(private vcRef: ViewContainerRef, private compiler: Compiler, private http: Http) { } 

    ngOnInit() { 
    this.http.get(this.url) 
     .map(res => res.text()) 
     .subscribe(
     (html) => { 
      this.html = html; 
      if (!html) return; 

      if(this.cmpRef) { 
      this.cmpRef.destroy(); 
      } 

      const compMetadata = new Component({ 
      selector: 'dynamic-html', 
      template: this.html, 
      }); 

      createComponentFactory(this.compiler, compMetadata) 
      .then(factory => { 
       const injector = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector); 
       this.cmpRef = this.vcRef.createComponent(factory, 0, injector, []); 
      }); 
     }, 
     err => console.log(err), 
     () => console.log('MvcPartial complete') 
    ); 

    } 

    ngOnDestroy() { 
    if(this.cmpRef) { 
     this.cmpRef.destroy(); 
    } 
    } 
} 

의 일부-component.html

@{ 
    ViewBag.Title = "This is some MVC stuff!!!"; 
} 
<div> 
    <h2>MVC Stuff:</h2> 
    <h4>@ViewBag.Title</h4> 
    <h2>Angular Stuff:</h2> 
    <h4>{{1 + 1}}</h4> 
</div> 
MvcStuff.cshtml

<mvc-partial [url]="'/stuffs/mvcstuff'"></mvc-partial> 

(당신의 MVC 응용 프로그램을 공유하여 스파 도메인을 가정)

in StuffsController.CS

public PartialViewResult MvcStuff() => PartialView(); 
+0

이것은 올바른 대답입니다. 매력처럼 작동합니다. 서버에서 Angular 템플릿을 미리 렌더링하는 것이 좋다고 생각합니다. 따라서 UserName을 쉽게 렌더링하거나 다른 사용자 별 비즈니스 로직 (권한 등)을 쉽게 수행 할 수 있습니다. –

+0

이것이 유일한 방법입니다. – k11k2

+0

' 'undefined'를 얻는 것이 'ComponentFactory '유형에 할당 할 수 없습니다. '오류 – k11k2

-1
+0

감사를 표시하지만, 위의 튜토리얼도 내 질문을 해결하고, 그것을 가지고 그 이유는대로 ViewRender 클래스를 생성하고 startup.cs 파일로 주입 명령을 추가해야합니다 대답을 찾는 것이 너무 어려웠습니다. 웹에서 다른 모든 튜토리얼처럼 MVC 내부에 앵귤러 스파를 설정하는 방법에 대해서도 설명합니다. MVC 부분 및 각도 구성 요소를 같은 페이지에 렌더링하는 방법은 다루지 않습니다. –

1

나는 이런 식으로했다.

@Component({ 
    templateUrl: '/Template/Index' 
}) 
export class TemplateComponent {} 

"/ Template/Index"는 MVC 컨트롤러의 URL이며 그 다음 방법입니다.

public IActionResult Index() 
    { 
    return PartialView(); 
    } 

제 문제는 매번 컨트롤러 메서드를 호출 할 때마다 뷰를 새로 고치는 방법을 알지 못합니다.

+1

이것은 웹팩에서는 작동하지 않습니다. –

+0

감사합니다. –

0

가 나는 HttpClient를 갔지 방법에 의해 호출 내 각 4 응용 프로그램에서 MVC PartialView의 HTML을 사용하는 데 필요한.

나는 HTML 문자열 내 부분보기를 변환

AMD's post을 사용했다.

public class HtmlReturn 
    { 
     public string html { get; set; } 
    } 

    [Produces("application/json")] 
    [Route("api/MVC/[action]")] 
    public class MVCController : Controller 
    { 

     private readonly ViewRender view; 

     public MVCController(ViewRender view) 
     {   
      this.view = view; 
     } 

     public IActionResult Index(string path) 
     { 
      data.html = this.view.Render("viewpath", viewModel); 
      return Json(data); 
     } 
} 

있습니다 서버에 ...

...in the template 
     <div class="files" [innerHtml]="myTemplate"> 
     </div> 

... in the component .ts file 
     export interface htmldata { 
      html: string; 
     } 


... inside component 

    getDivHtml(path: string): Promise<htmldata> { 
      return this.http 
       .get<htmldata>(`${this.baseUrl}/MVC/Index?path=` + path , { withCredentials: true }) 
       .toPromise(); 
    } 

    ngOnInit() { 
     this.getDivHtml('').then(
      data => { this.loadData(data); }, 
     ).catch(error => { console.log(error); }); 
    } 

    loadData(data: htmldata) { 
     this.myTemplate = data.html; 
    } 

: 나는 컨테이너 JSON 오브젝트이 반환, 내 page..thus에 사업부의 HTML을 설정 변수로 설정 : 이것은 이벤트 리스너가 필요없는 정적 HTML에서만 잘 작동합니다. 나는 전문가가 아니기 때문에 렌더러 2를 사용하여로드 된 HTML에 클릭 이벤트를 추가 할 수 없었습니다. 가능할 수도 있습니다.

AMDs 게시물에 응답하는