我将我的角度2更新到版本4.0.3然后在忙碌的stoped工作,我得到了这个例外:
错误错误:找到合成属性@fadeInOut。请包含" BrowserAnimationsModule"或者" NoopAnimationsModule"在你的申请中。
我的ts组件代码:
import {Component, OnInit, OnDestroy, ViewChild, ElementRef} from '@angular/core';
import {NgForm} from '@angular/forms';
import {AdminService} from "../../../services/admin.service";
import {HttpService} from "../../../../http.service";
import {Subscription} from "rxjs";
import {Http, Response, Headers,RequestOptions} from "@angular/http";
import {ActivatedRoute} from "@angular/router";
@Component({
selector: 'app-products-form',
templateUrl: './products-form.component.html',
styleUrls: ['./products-form.component.css']
})
export class ProductsFormComponent implements OnInit, OnDestroy {
product:any = {'needTransformer':'Yes', 'power':'', 'cct':'', 'cri':'', 'lightSource':'', 'country':'','category':{}, 'productionCompany':{},'finish':{}};
companies: string[] =[];
companiesSubscription: Subscription;
finishes: string[] = [];
finishesSubscription: Subscription;
categories: string[] = [];
categoriesSubscription: Subscription;
lightSources: string[] = [];
lightSourcesSubscription: Subscription;
countries: string[] = [];
countriesSubscription: Subscription;
routeSubscritpion: Subscription;
selectedCategory: string;
selectedFinish: string;
selectedProductionCompany: string;
selectedLightSource: string;
selectedCountry: string;
selectedTransformerNeeded: string;
isEdit: boolean = false;
@ViewChild('mainImage') mainImage: ElementRef;
@ViewChild('diemsnions') diemsnions: ElementRef;
@ViewChild('effects') effects: ElementRef;
@ViewChild('pdf') pdf: ElementRef;
@ViewChild('categoryEl') categoryEl: ElementRef;
busy: any;
constructor(private httpService:HttpService, private adminService: AdminService, private http: Http, private route: ActivatedRoute) { }
ngOnInit() {
// this.busy = true;
this.routeSubscritpion = this.route.params.subscribe(param => {
let code = param['code'];
if(code !='undefined')
this.httpService.getProductDataByCode(code).subscribe(
(data:any)=> {
this.product=data;
this.isEdit = true;
this.selectedCategory = data.category.name;
this.selectedFinish = data.finish.name;
this.selectedCountry = data.country;
this.selectedProductionCompany = data.productionCompany.name;
this.selectedLightSource = data.lightSource;
this.selectedTransformerNeeded = data.transformerNeeded;
// this.categoryEl.nativeElement.value = data.category.name;
},
(err) => console.error(err+"<-------------"),
() => console.log('Random Quote Complete')
);
});
this.companiesSubscription = this.httpService.getAllCompanies().subscribe(
(data:any)=> {
data.forEach((entry)=> {
this.companies.push(entry.name);
});
if(this.companies.length > 0)
this.product.productionCompany = this.companies[0];
},
(err) => console.error(err+"<-------------"),
() => console.log('Random Quote Complete')
);
this.categoriesSubscription = this.httpService.getAllCategories().subscribe(
(data:any)=> {
data.forEach((entry)=> {
this.categories.push(entry.name);
});
if(this.categories.length > 0)
this.product.category = this.categories[0];
},
(err) => console.error(err+"<-------------"),
() => console.log('Random Quote Complete')
);
this.finishesSubscription = this.httpService.getAllFinishes().subscribe(
(data:any)=> {
data.forEach((entry)=> {
this.finishes.push(entry.name);
});
if(this.finishes.length > 0)
this.product.finish = this.finishes[0];
},
(err) => console.error(err+"<-------------"),
() => console.log('Random Quote Complete')
);
this.lightSourcesSubscription = this.httpService.getAllLightSources().subscribe(
(data:any)=> {
this.lightSources = data;
if(this.lightSources.length > 0)
this.product.lightSource = this.lightSources[0];
},
(err) => console.error(err+"<-------------"),
() => console.log('Random Quote Complete')
);
this.lightSourcesSubscription = this.httpService.getAllCountries().subscribe(
(data:any)=> {
this.countries = data;
if(this.countries.length > 0)
this.product.country = this.countries[0];
},
(err) => console.error(err+"<-------------"),
() => console.log('Random Quote Complete')
);
}
formatStrings(str)
{
str=str.replace(/\s/g, '');
str=str.replace(/,/g, '');
str=str.toUpperCase();
return str
}
onSubmit(form:NgForm)
{
var values=form.value;
let parent=this;
let obj={
name:values.name,
description:values.description,
code:values.code,
category:{
name:values.categories
},
productionCompany:{
name:values.productionCompany
},
finish:{
name:values.finish
},
transformerNeeded:values.transformerNeeded,
power:values.power,
cct:values.cct,
cri:values.cri,
ik: values.ik,
ip: values.ip,
luminous: values.luminous,
optic: values.optic,
lightSource:values.lightSource,
country:values.productionContry,
effictImagePath:'',
normalImagePath:'',
detailsImagePath:'',
catalogPath:''
};
let headers = new Headers({ 'Content-Type': 'application/json' ,'Authorization': JSON.parse(localStorage.getItem('currentUser'))['token']});
let options = new RequestOptions({ headers: headers });
if(!this.isEdit) {
this.busy = this.http.post('http://localhost:8090/products/', JSON.stringify(obj), options).subscribe(
(data: any) => {
parent.upload(obj.code)
},
(err) => console.error(err + "<-------------"),
() => console.log("")
);
} else {
obj.effictImagePath = this.product.effictImagePath;
obj.normalImagePath = this.product.normalImagePath;
obj.detailsImagePath = this.product.detailsImagePath;
obj.catalogPath = this.product.catalogPath;
this.busy = this.http.put('http://localhost:8090/products/'+obj.code, JSON.stringify(obj), options).subscribe(
(data: any) => {
parent.upload(obj.code)
},
(err) => console.error(err + "<-------------"),
() => console.log("")
);
}
console.log(JSON.stringify(obj));
}
ngOnDestroy() {
this.companiesSubscription.unsubscribe();
this.finishesSubscription.unsubscribe();
this.lightSourcesSubscription.unsubscribe();
}
changeFinish(finish) {
this.product.finish = finish;
console.log(this.product);
}
makeFileRequest(url:string) {
return new Promise((resolve, reject) => {
let mainImageEl: HTMLInputElement = this.mainImage.nativeElement;
let formData = new FormData();
let xhr = new XMLHttpRequest();
if (mainImageEl.files.length > 0)
formData.append("normalImagePath", mainImageEl.files.item(0), mainImageEl.files.item(0).name);
let diemsnionsEl: HTMLInputElement = this.diemsnions.nativeElement;
if (diemsnionsEl.files.length > 0)
formData.append("detailsImagePath", diemsnionsEl.files.item(0), diemsnionsEl.files.item(0).name);
let effectsEl: HTMLInputElement = this.effects.nativeElement;
if (effectsEl.files.length > 0)
formData.append("effictImagePath", effectsEl.files.item(0), effectsEl.files.item(0).name);
let pdfEl: HTMLInputElement = this.pdf.nativeElement;
if (pdfEl.files.length > 0)
formData.append("catalogPath", pdfEl.files.item(0), pdfEl.files.item(0).name);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
resolve(JSON.parse(xhr.response));
} else {
reject(xhr.response);
}
}
};
xhr.setRequestHeader("Authorization", JSON.parse(localStorage.getItem('currentUser'))['token']);
xhr.open("POST", url, true);
xhr.send(formData);
});
}
upload(code: string) {
this.busy = this.makeFileRequest("http://levelskw.com/products/upload/"+code).then((result) => {
console.log(result);
}, (error) => {
console.error(error);
});
}
}
Html代码:
<div [ngBusy]="busy"></div>
<div class="main-container">
<form (ngSubmit)="onSubmit(f)" #f="ngForm">
<div fxLayout="column" fxLayoutGap="15px">
<div fxLayout="row" fxLayoutGap="29px">
<div fxLayout="column" fxLayoutGap="20px">
<div fxLayout="column" class='titleSection'>
<div class="header"><div class='header-label'>Header</div></div>
<div class='title'><input type="text" placeholder="Code" name="code" [(ngModel)]="product.code" /></div>
<div class='title'><input type="text" placeholder="Name" name="name" [(ngModel)]="product.name" /></div>
<div class="description"><textarea placeholder="Description" name="description" [(ngModel)]="product.description"></textarea></div>
</div>
<div fxLayout="column" class="loadSection">
<div class="header"><div class='header-label'>Images</div></div>
<div fxLayout="column" class="img-section" fxLayoutGap="2px">
<div class="img-lable">Main image</div>
<div class="img-btn">
<button fxLayoutAlign="center center">Upload</button>
<input type="file" #mainImage/>
</div>
</div>
<div fxLayout="column" class="img-section" fxLayoutGap="2px">
<div class="img-lable">Dimensions</div>
<div class="img-btn">
<button fxLayoutAlign="center center">Upload</button>
<input type="file" #diemsnions/>
</div>
</div>
<div fxLayout="column" class="img-section" fxLayoutGap="2px">
<div class="img-lable">Effects</div>
<div class="img-btn">
<button fxLayoutAlign="center center">Upload</button>
<input type="file" #effects/>
</div>
</div>
<div fxLayout="column" class="img-section" fxLayoutGap="2px">
<div class="img-lable">PDF</div>
<div class="img-btn">
<button fxLayoutAlign="center center">Upload</button>
<input type="file" #pdf/>
</div>
</div>
</div>
</div>
<div fxLayout="column" class="details" fxLayoutGap="10px">
<div class="header"><div class='header-label'>Related Products</div></div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>Category</div>
<select class="dropdown" name="categories" [(ngModel)]="selectedCategory">
<option *ngFor="let category of categories" [ngValue]="category">{{category}}</option>
</select>
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>Manufactured By</div>
<select class="dropdown" name="productionCompany" [(ngModel)]="selectedProductionCompany">
<option *ngFor="let company of companies" [ngValue]="company">{{company}}</option>
</select>
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>Materials</div>
<select class="dropdown" name="finish" [(ngModel)]="selectedFinish">
<option *ngFor="let finish of finishes" [ngValue]="finish">{{finish}}</option>
</select>
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>Transformer needed</div>
<select class="dropdown" name="transformerNeeded" [(ngModel)]="selectedTransformerNeeded">
<option value="true" selected>Yes</option>
<option value="false" >No</option>
</select>
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>Power(W)</div>
<input type="text" name="power" [(ngModel)]="product.power"/>
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>CCT(K)</div>
<input type="text" name="cct" [(ngModel)]="product.cct"/>
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>IK</div>
<input type="text" name="ik" [(ngModel)]="product.ik"/>
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>Index of protection</div>
<input type="text" name="ip" [(ngModel)]="product.ip"/>
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>Luminous</div>
<input type="text" name="luminous" [(ngModel)]="product.luminous"/>
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>Optic</div>
<input type="text" name="optic" [(ngModel)]="product.optic"/>
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>CRI</div>
<input type="text" name="cri" [(ngModel)]="product.cri"/>
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>Light Source</div>
<select class="dropdown" name="lightSource" [(ngModel)]="selectedLightSource">
<option *ngFor="let lightSource of lightSources" [ngValue]="formatStrings(lightSource)" >{{lightSource}}</option>
</select>
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>Production country</div>
<select class="dropdown" name="productionContry" [(ngModel)]="selectedCountry">
<option *ngFor="let company of countries" [ngValue]="formatStrings(company)" >{{company}}</option>
</select>
</div>
</div>
</div>
</div>
<div class='control-btn-container'>
<div fxLayout="row" fxLayoutGap="10px">
<button class="btn cancel" fxLayoutAlign="center center">Cancel</button>
<button type="submit" class="btn save" fxLayoutAlign="center center">Save</button>
</div>
</div>
</div>
</form>
</div>
pakage.json
{
"name": "levels",
"version": "0.0.0",
"license": "MIT",
"angular-cli": {},
"scripts": {
"ng": "ng",
"start": "ng serve",
"lint": "tslint \"src/**/*.ts\" --project src/tsconfig.json --type-check && tslint \"e2e/**/*.ts\" --project e2e/tsconfig.json --type-check",
"test": "ng test",
"pree2e": "webdriver-manager update --standalone false --gecko false",
"e2e": "protractor"
},
"private": true,
"dependencies": {
"@angular/animations": "^4.0.3",
"@angular/common": "^4.0.3",
"@angular/compiler": "^4.0.2",
"@angular/compiler-cli": "^4.0.2",
"@angular/core": "^4.0.2",
"@angular/flex-layout": "^2.0.0-rc.1",
"@angular/forms": "^4.0.2",
"@angular/http": "^4.0.2",
"@angular/material": "^2.0.0-beta.2",
"@angular/platform-browser": "^4.0.2",
"@angular/platform-browser-dynamic": "^4.0.2",
"@angular/platform-server": "^4.0.2",
"@angular/router": "^4.0.2",
"angular2-busy": "https://github.com/dinusuresh/angular2-busy.git",
"angular2-spinner": "^1.0.9",
"core-js": "^2.4.1",
"md2": "0.0.17-2",
"ng2-file-upload": "^1.2.0",
"ng2-file-uploader": "^0.1.4",
"ng2-material-select": "^0.1.8",
"ngx-uploader": "^2.2.5",
"rxjs": "^5.0.1",
"ts-helpers": "^1.1.1",
"typescript": "^2.2.2",
"zone.js": "^0.8.5"
},
"devDependencies": {
"@angular/cli": "^1.0.0",
"@angular/compiler-cli": "^4.0.2",
"@angular2-material/progress-circle": "^2.0.0-alpha.8-2",
"@types/jasmine": "2.5.47",
"@types/node": "^7.0.12",
"angular-2-dropdown-multiselect": "^1.0.6",
"codelyzer": "~2.1.1",
"jasmine-core": "2.5.2",
"jasmine-spec-reporter": "3.3.0",
"karma": "1.6.0",
"karma-chrome-launcher": "^2.0.0",
"karma-cli": "^1.0.1",
"karma-jasmine": "^1.0.2",
"karma-remap-istanbul": "^0.6.0",
"protractor": "~5.1.1",
"ts-node": "3.0.2",
"tslint": "^5.1.0",
"typescript": "~2.2.2"
}
}
答案 0 :(得分:6)
错误明确指出您需要导入BrowserAnimationsModule
,因为Angular 4发布动画模块已从@angular/core
移出。它已被移出到单独的模块@angular/platform-browser/animations
。除此之外,如果您正在使用systemjs
模块加载器
'@angular/animations': 'npm:@angular/animations/bundles/animations.umd.js',
'@angular/animations/browser': 'npm:@angular/animations/bundles/animations-browser.umd.js',
'@angular/platform-browser/animations': 'npm:@angular/platform-browser/bundles/platform-browser-animations.umd.js',
然后从BrowserAnimationsModule
模块中app.module.ts
内导入@angular/platform-browser/animations
。然后将其放在imports
AppModule
选项中
来自changelog的