2017-04-05 61 views
0

我已经花了很多时间在这个上面挥舞着白旗。Angular2 - asp.core - 路由到指定网址时无法绑定指令

当我从index.html运行时,我的应用程序工作正常,我懒加载一个功能,它使用绑定来为测试目的应用样式。

但是如果我直接去了网址,我得到异常

"Call to Node module failed with error: Error: Uncaught (in promise): TypeError: Cannot set property 'padding' of undefined".

是什么让事情更难的是,亮点指令正常工作,它只是我的标签指令不结合。如果我从我的html中删除标签属性,页面加载正常。我真的很难找到造成这个问题的问题。

应用模块

import { NgModule } from '@angular/core'; 
import { UniversalModule } from 'angular2-universal'; 
import { ReactiveFormsModule, FormsModule } from '@angular/forms'; 
import { HttpModule } from '@angular/http'; 

import { AppComponent } from './components/app/app.component' 
import { NavMenuComponent } from './components/navmenu/navmenu.component'; 
import { HomeComponent } from './components/home/home.component'; 
import { FetchDataComponent } from './components/fetchdata/fetchdata.component'; 
import { CounterComponent } from './components/counter/counter.component'; 
import { HeroDetailComponent } from './components/hero/hero-detail.component'; 
import { HeroListComponent } from './components/hero/hero-list.component'; 
import { HeroService } from './components/hero/hero.service'; 
import { HeroDashboardComponent } from './components/hero/hero-dashboard.component'; 
import { HeroMainComponent } from './components/hero/hero-main.component'; 
import { HeroFormComponent } from './components/form/hero-form.component'; 

import { ReactiveFormModule } from './components/form-reactive/form-reactive.module'; 

import { CoreModule } from './components/core/core.module'; 

import { AppRoutingModule } from './app.routes' 

@NgModule({ 
    bootstrap: [AppComponent], 
    imports: [ 
     UniversalModule, // Must be first import. This automatically imports BrowserModule, HttpModule, and JsonpModule too. 
     HttpModule, 
     FormsModule, 
     AppRoutingModule, 
     ReactiveFormsModule, 
     CoreModule, 
     ReactiveFormModule 
    ], 
    declarations: [ 
     AppComponent, 
     NavMenuComponent, 
     CounterComponent, 
     FetchDataComponent, 
     HomeComponent, 
     HeroDetailComponent, 
     HeroListComponent, 
     HeroDashboardComponent, 
     HeroMainComponent, 
     HeroFormComponent 
    ], 
    providers: [HeroService] 
}) 

export class AppModule {} 

app.routes.ts

import { NgModule } from '@angular/core'; 
import { Routes, RouterModule } from '@angular/router'; 
import { HomeComponent } from './components/home/home.component'; 
import { FetchDataComponent } from './components/fetchdata/fetchdata.component'; 
import { CounterComponent } from './components/counter/counter.component'; 
import { HeroDetailComponent } from './components/hero/hero-detail.component'; 
import { HeroListComponent } from './components/hero/hero-list.component'; 
import { HeroDashboardComponent } from './components/hero/hero-dashboard.component'; 
import { HeroMainComponent } from './components/hero/hero-main.component'; 
import { HeroFormComponent } from './components/form/hero-form.component';  

export const routes: Routes = [ 
    { path: '', redirectTo: 'hero/dashboard', pathMatch: 'full' }, 
    { path: 'home', component: HomeComponent }, 
    { path: 'counter', component: CounterComponent }, 
    { path: 'fetch-data', component: FetchDataComponent }, 
    { 
     path: 'hero', component: HeroMainComponent, children: 
     [ 
      { path: '', component: HeroListComponent }, // url: hero/ 
      { path: 'dashboard', component: HeroDashboardComponent }, 
      { path: 'detail/:id', component: HeroDetailComponent }, 
     ] 
    }, 
    { path: 'form', component: HeroFormComponent }, 
    { path: 'form-reactive', loadChildren:() => { return Promise.resolve(require('./components/form-reactive/form-reactive.module')['ReactiveFormModule']) }}, 
    { path: 'core-tracking', loadChildren:() => { return Promise.resolve(require('./components/core/core.module')['CoreModule']); } }, 
    { path: '**', redirectTo: 'home' } 
] 

@NgModule({ 
    imports: [RouterModule.forRoot(routes)], 
    exports: [RouterModule] 
}) 
export class AppRoutingModule { } 

芯routing.module.ts

import { NgModule } from '@angular/core'; 
import { RouterModule } from '@angular/router'; 
import { CoreTrackingMainComponent } from './coreTrackingMain.component'; 

@NgModule({ 
    imports: [RouterModule.forChild([ 
     { path: '', component: CoreTrackingMainComponent } 
    ])], 
    exports: [RouterModule] 
}) 
export class ContactRoutingModule { } 

core.module.ts

import { NgModule } from '@angular/core'; 
import { CommonModule } from '@angular/common'; 
import { ReactiveFormsModule } from '@angular/forms'; 
import { ContactRoutingModule } from './core-routing.module'; 

import { CoreTrackingMainComponent } from './coreTrackingMain.component'; 
import { CoreTrackingCriteriaComponent } from './coreTrackingCriteria.component'; 
import { CriteriaLabelDirective } from './coreCriteriaLabel.directive'; 
import { HighlightDirective } from './coreCriteriaHighlight.directive'; 


@NgModule({ 
    imports: [CommonModule, ReactiveFormsModule, ContactRoutingModule], 
    declarations: [ 
     CoreTrackingMainComponent, 
     CoreTrackingCriteriaComponent, 
     CriteriaLabelDirective, 
     HighlightDirective, 
    ], 
    exports: [ 
     CoreTrackingMainComponent, 
     CoreTrackingCriteriaComponent 
    ] 
}) 
export class CoreModule { } 

coreCriteriaLabel.directive.ts

import { Directive, ElementRef } from '@angular/core'; 

    @Directive({ selector: '[myLabel]' }) 

    export class CriteriaLabelDirective { 
     constructor(el: ElementRef) { 
      el.nativeElement.style.padding = '6px 0'; 
} 
     } 

coreCriteriaHighlight.directive.ts

import { Directive, ElementRef, HostListener, Input } from '@angular/core'; 
@Directive({ selector: '[myHighlight]' }) 

export class HighlightDirective { 
    @Input('myHighlight') highlightColor: string; 
    constructor(private el: ElementRef) { } 
    @HostListener('mouseenter') onMouseEnter() { 
     this.highlight(this.highlightColor || 'red'); 
    } 
    @HostListener('mouseleave') onMouseLeave() { 
     this.highlight(null); 
    } 
    private highlight(color: string) { 
     this.el.nativeElement.style.backgroundColor = color; 
    } 
} 

coreTrackingCriteria.component.html

<h2>Core Tracking Criteria</h2> 
<div class="criteria-container col-xs-12"> 
    <form [formGroup]="trackingForm" novalidate> 
     <div class="form-group"> 
      <div class="col-md-6"> 
       <label [myHighlight]="color" class="control-label col-xs-4">Reader Organization</label> 
       <div class="col-xs-8"> 
        <input class="form-control" formControlName="readerOrg"> 
       </div> 
      </div> 
      <div class="col-md-6"> 
       <label [myLabel] class="control-label col-xs-4">Location</label> 
       <div class="col-xs-8"> 
        <input class="form-control" formControlName="location"> 
       </div> 
      </div> 
     </div> 
    </form> 
</div> 

coreTrackingCriteria.component.ts

import { Component } from '@angular/core'; 
import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; 

@Component({ 
    selector: 'core-criteria', 
    templateUrl: './coreTrackingCriteria.component.html', 
    styleUrls: ['./coreTrackingCriteria.component.css'] 
}) 
export class CoreTrackingCriteriaComponent { 

    constructor(private fb: FormBuilder) { 
     this.createForm(); 
    } 

    color: string = 'blue'; 

    trackingForm: FormGroup; 

    createForm() { 
     this.trackingForm = this.fb.group({ 
      readerOrg: ['', Validators.required], 
      location: ['', Validators.required], 
     }); 
    } 

} 

Update

实现ngOnInit()而不是在指令中使用构造函数。还是引起了同样的问题

coreCriteriaLabel.directive.ts

import { Directive, ElementRef, Input, OnInit } from '@angular/core'; 

@Directive({ selector: '[myLabel]' }) 

export class CriteriaLabelDirective implements OnInit { 

    constructor(private el: ElementRef) { 
    } 

    ngOnInit() { 
     this.el.nativeElement.style.padding = '6px 0'; 
    } 
} 
+0

可以显示在使用这个指令的HTML? –

+1

在哪里以及如何使用myLabel?你有没有试过移动'el.nativeElement.style。padding ='6px 0';'to'ngOnInit()'或'ngAfterContentInit()'(应该不是必须的)? –

+0

更新了我的文章,@günter-zöchbauer我应该将ngOnInit()应用于我的指令,我认为这些钩子通常应用于组件 – redstubble

回答

0

OK,我终于得到了我的指示。

  1. 我使用Renderer类而不是直接附加到 元素nativeElement。
  2. 我还需要包含@Input 修饰器才能正确编译应用程序。

    任何解释此行为的原因将不胜感激。

    import { Directive, Renderer, ElementRef, Input, } from '@angular/core'; 
    @Directive({ selector: '[myLabel]' }) 
    
    export class CriteriaLabelDirective { 
        @Input('myLabel') myLabel; 
        constructor(private renderer: Renderer, private el: ElementRef) { 
          this.renderer.setElementStyle(this.el.nativeElement, 'padding', '6px 0'); 
        } 
    }