Angular 2 的组件装饰器中的指令属性发生了什么变化? [英] What happened to the directives property in the Component decorator for Angular 2?

查看:35
本文介绍了Angular 2 的组件装饰器中的指令属性发生了什么变化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Angular CLI v1.0.0-beta.19-3 来搭建脚手架/build 一个 Angular 2 网站.我按如下方式生成组件ng g component file-upload.

我注意到生成的组件 file-upload.component.ts 如下所示.

@Component({选择器:'文件上传',templateUrl: './file-upload.component.html',styleUrls: ['./file-upload.component.css']})导出类 FileUploadComponent 实现 OnInit {...}

我需要使用这个组件,ng2-file-upload,在我自己的组件中.所以我尝试在 @Component 装饰器上添加 directives 属性,但是,我在 VS 代码.

@Component({选择器:'文件上传',templateUrl: './file-upload.component.html',styleUrls: ['./file-upload.component.css'],指令:[ FILE_UPLOAD_DIRECTIVES ]})导出类 FileUploadComponent 实现 OnInit {...}

<预>[ts] '{ selector: string; 类型的参数模板网址:字符串;styleUrls: 字符串[];指令:未定义[];}' 不可分配给组件"类型的参数.对象字面量只能指定已知属性,并且组件"类型中不存在指令".

我的导入如下所示.

import { Component, OnInit, Input } from '@angular/core';从 '@angular/common' 导入 { NgClass, NgStyle };import { FileSelectDirective, FileDropDirective, FileUploadModule, FileUploader, FileUploaderOptions } from 'ng2-file-upload';

当我运行应用ng serve时,我看到控制台报告了以下错误.

<预>zone.js:388 未处理的承诺拒绝:模板解析错误:无法绑定到uploader",因为它不是div"的已知属性.("[ngClass]="{'nv-file-over': hasBaseDropZoneOver}"(fileOver)="fileOverBase($event)"[错误 ->][上传者]="上传者"class="well my-drop-zone">

这是我在 package.json 中的依赖项.

<代码>{"name": "app-www",版本":0.0.0","许可证": "麻省理工学院",角度cli":{},脚本":{"start": "ng serve","lint": "tslint \"src/**/*.ts\"","test": "ng 测试","pree2e": "webdriver-manager 更新","e2e": "量角器"},私人":真的,依赖关系":{"@angular/common": "~2.1.1","@angular/compiler": "~2.1.1","@angular/core": "~2.1.1","@angular/forms": "~2.1.1","@angular/http": "~2.1.1","@angular/platform-b​​rowser": "~2.1.1","@angular/platform-b​​rowser-dynamic": "~2.1.1","@angular/router": "~3.1.1","angular2-cookie": "^1.2.5","引导程序": "^3.3.7","core-js": "^2.4.1","jquery": "^3.1.1","lodash": "^4.16.6","ng2-bootstrap": "^1.1.16","ng2-file-upload": "^1.1.2","rxjs": "5.0.0-beta.12","ts-helpers": "^1.1.1",zone.js":^0.6.25"},开发依赖":{"@types/jasmine": "^2.2.30","@types/lodash": "^4.14.38","@types/node": "^6.0.45","angular-cli": "1.0.0-beta.19-3","codelyzer": "1.0.0-beta.1","jasmine-core": "2.4.1","jasmine-spec-reporter": "2.5.0","业力": "1.2.0","karma-chrome-launcher": "^2.0.0","karma-cli": "^1.0.1","karma-jasmine": "^1.0.2","karma-remap-istanbul": "^0.2.1","量角器": "4.0.9","ts-node": "1.2.1","tslint": "3.13.0","打字稿": "~2.0.3",webdriver-manager":10.2.5"}}

文档说要使用这个导入语句.

import { FILE_UPLOAD_DIRECTIVES } from 'ng2-file-upload';

但是在 VS Code 中,它说明了以下内容.

<预>[ts] 模块 '"/Users/jwayne/git/app-www/node_modules/ng2-file-upload/ng2-file-upload"' 没有导出成员 'FILE_UPLOAD_DIRECTIVES'.

更有趣的是,我创建了自己的登录组件,如下所示.

@Component({选择器:'登录组件',templateUrl: './login.component.html',styleUrls: ['./login.component.css']})导出类 LoginComponent 实现 OnInit {...}

为了在另一个组件中使用它,我什至不必再将它作为指令或类似的东西引用.例如,我有一个使用此登录组件的默认组件.HTML 如下所示.

代码如下所示(注意组件装饰器没有指令属性).

@Component({选择器:应用默认",templateUrl: './default.component.html',styleUrls: ['./default.component.css']})导出类 DefaultComponent 实现 OnInit、OnDestroy {...}

虽然现在修改了 app.module.ts 文件.

import { LoginComponent } from './login/login.component';import { DefaultComponent } from './default/default.component';@NgModule({声明: [应用组件,登录组件,默认组件],进口:[浏览器模块,表单模块,Http模块,RouterModule.forRoot([{ path: 'default', 组件: DefaultComponent },{ path: 'main', 组件: MainComponent, canActivate: [ UserAuthGuard ] },{ path: '', redirectTo: '/default', pathMatch: 'full' },{ 路径:'**',重定向到:'/默认'}])],供应商: [用户验证保护],引导程序:[AppComponent]})导出类 AppModule { }

所以,有很多事情发生,但首先,组件装饰器的指令属性发生了什么变化?

解决方案

解决这个问题的关键是在 app.module.ts 中导入指令,然后用 @NgModule 声明它们.这是 app.module.ts 的一个片段.

import { FileSelectDirective, FileDropDirective} from 'ng2-file-upload';从 './app.component' 导入 { AppComponent };@NgModule({声明: [应用组件,FileSelectDirective, FileDropDirective],进口:[浏览器模块,表单模块,Http模块,RouterModule.forRoot([{ path: 'default', 组件: DefaultComponent },{ path: 'main', 组件: MainComponent, canActivate: [ UserAuthGuard ] },{ path: '', redirectTo: '/default', pathMatch: 'full' },{ 路径:'**',重定向到:'/默认'}])],提供者:[ ... ],引导程序:[AppComponent]})导出类 AppModule { }

在我的组件中,我仍然需要导入指令.这是另一个片段.

import { Component, OnInit, Input } from '@angular/core';从 '@angular/common' 导入 { NgClass, NgStyle };进口 {文件选择指令,FileDrop 指令,文件上传器,文件上传选项来自'ng2-file-upload';import * as _ from 'lodash';从'../service/login.service'导入{登录服务};@成分({选择器:'文件上传',templateUrl: './file-upload.component.html',styleUrls: ['./file-upload.component.css']})导出类 FileUploadComponent 实现 OnInit {//省略正文}

I am using the Angular CLI v1.0.0-beta.19-3 to scaffold/build an Angular 2 website. I generate my component as follows ng g component file-upload.

I noticed that the generated component file-upload.component.ts looks like the following.

@Component({
  selector: 'file-upload',
  templateUrl: './file-upload.component.html',
  styleUrls: ['./file-upload.component.css']
})
export class FileUploadComponent implements OnInit {
 ...
}

I need to use this component, ng2-file-upload, inside my own component. So I try to add the directives property on the @Component decorator, however, I get an error in VS Code.

@Component({
  selector: 'file-upload',
  templateUrl: './file-upload.component.html',
  styleUrls: ['./file-upload.component.css'],
  directives: [ FILE_UPLOAD_DIRECTIVES ]
})
export class FileUploadComponent implements OnInit {
 ...
}

[ts] Argument of type '{ selector: string; templateUrl: string; styleUrls: string[]; directives: undefined[]; }' is not assignable to parameter of type 'Component'.
       Object literal may only specify known properties, and 'directives' does not exist in type 'Component'.

And my imports look like the following.

import { Component, OnInit, Input } from '@angular/core';
import { NgClass, NgStyle } from '@angular/common';
import { FileSelectDirective, FileDropDirective, FileUploadModule, FileUploader, FileUploaderOptions } from 'ng2-file-upload';

When I run the app ng serve, I see the following error reported in the console.

zone.js:388 Unhandled Promise rejection: Template parse errors:
Can't bind to 'uploader' since it isn't a known property of 'div'. ("
  [ngClass]="{'nv-file-over': hasBaseDropZoneOver}"
  (fileOver)="fileOverBase($event)"
  [ERROR ->][uploader]="uploader"
  class="well my-drop-zone">

Here's my dependencies in package.json.

{
  "name": "app-www",
  "version": "0.0.0",
  "license": "MIT",
  "angular-cli": {},
  "scripts": {
    "start": "ng serve",
    "lint": "tslint \"src/**/*.ts\"",
    "test": "ng test",
    "pree2e": "webdriver-manager update",
    "e2e": "protractor"
  },
  "private": true,
  "dependencies": {
    "@angular/common": "~2.1.1",
    "@angular/compiler": "~2.1.1",
    "@angular/core": "~2.1.1",
    "@angular/forms": "~2.1.1",
    "@angular/http": "~2.1.1",
    "@angular/platform-browser": "~2.1.1",
    "@angular/platform-browser-dynamic": "~2.1.1",
    "@angular/router": "~3.1.1",
    "angular2-cookie": "^1.2.5",
    "bootstrap": "^3.3.7",
    "core-js": "^2.4.1",
    "jquery": "^3.1.1",
    "lodash": "^4.16.6",
    "ng2-bootstrap": "^1.1.16",
    "ng2-file-upload": "^1.1.2",
    "rxjs": "5.0.0-beta.12",
    "ts-helpers": "^1.1.1",
    "zone.js": "^0.6.25"
  },
  "devDependencies": {
    "@types/jasmine": "^2.2.30",
    "@types/lodash": "^4.14.38",
    "@types/node": "^6.0.45",
    "angular-cli": "1.0.0-beta.19-3",
    "codelyzer": "1.0.0-beta.1",
    "jasmine-core": "2.4.1",
    "jasmine-spec-reporter": "2.5.0",
    "karma": "1.2.0",
    "karma-chrome-launcher": "^2.0.0",
    "karma-cli": "^1.0.1",
    "karma-jasmine": "^1.0.2",
    "karma-remap-istanbul": "^0.2.1",
    "protractor": "4.0.9",
    "ts-node": "1.2.1",
    "tslint": "3.13.0",
    "typescript": "~2.0.3",
    "webdriver-manager": "10.2.5"
  }
}

The doc says to use this import statement.

import { FILE_UPLOAD_DIRECTIVES } from 'ng2-file-upload';

But in VS Code, it says the following.

[ts] Module '"/Users/jwayne/git/app-www/node_modules/ng2-file-upload/ng2-file-upload"' has no exported member 'FILE_UPLOAD_DIRECTIVES'.

What's even more interesting, is that I created my own login component like the following.

@Component({
  selector: 'login-component',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
 ...
}

In order to use this in another component, I don't even have to reference it as a directive or anything like that anymore. For example, I have a default component that uses this login component. The HTML looks like the following.

<login-component></login-component>

And the code looks like the following (note no directive property for the component decorator).

@Component({
  selector: 'app-default',
  templateUrl: './default.component.html',
  styleUrls: ['./default.component.css']
})
export class DefaultComponent implements OnInit, OnDestroy {
 ...
}

Although the app.module.ts file is modified now.

import { LoginComponent } from './login/login.component';
import { DefaultComponent } from './default/default.component';
@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    DefaultComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    RouterModule.forRoot([
      { path: 'default', component: DefaultComponent },
      { path: 'main', component: MainComponent, canActivate: [ UserAuthGuard ] },
      { path: '', redirectTo: '/default', pathMatch: 'full' },
      { path: '**', redirectTo: '/default' }
    ])
  ],
  providers: [ 
    UserAuthGuard
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

So, there's a lot of stuff going on, but to start off, what happened to the directives property for the component decorator?

解决方案

The key to solving this problem was importing the directives in app.module.ts and then declaring them with @NgModule. Here's a snippet of app.module.ts.

import { FileSelectDirective, FileDropDirective} from 'ng2-file-upload';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent,
    FileSelectDirective, FileDropDirective
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    RouterModule.forRoot([
      { path: 'default', component: DefaultComponent },
      { path: 'main', component: MainComponent, canActivate: [ UserAuthGuard ] },
      { path: '', redirectTo: '/default', pathMatch: 'full' },
      { path: '**', redirectTo: '/default' }
    ])
  ],
  providers: [ ... ],
  bootstrap: [AppComponent]
})
export class AppModule { }

In my component, I still had to import the directives. Here's another snippet.

import { Component, OnInit, Input } from '@angular/core';
import { NgClass, NgStyle } from '@angular/common';
import { 
  FileSelectDirective,
  FileDropDirective, 
  FileUploader, 
  FileUploaderOptions 
} from 'ng2-file-upload';
import * as _ from 'lodash';
import { LoginService } from '../service/login.service';

@Component({
  selector: 'file-upload',
  templateUrl: './file-upload.component.html',
  styleUrls: ['./file-upload.component.css']
})
export class FileUploadComponent implements OnInit {
  //body omitted
}

这篇关于Angular 2 的组件装饰器中的指令属性发生了什么变化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆