我正在尝试在Angular 2中创建一个显示服务数据的组件.该服务基本上从用户的一些输入后从json文件加载一些数据.我一直试图让组件更新,但它似乎没有识别更改,除非我从我的服务提交事件后调用zone.run().组件的代码如下:
@Component({ selector: 'assess-asset-group',directives: [AssetComponent,AssetHeaderComponent,NgFor,NgIf],template: ` <div *ngIf="assetService.schema != null"> <div class="asset-group" *ngFor="#assetTypeName of assetService.schema.assetTypeNames"> <div class="asset-type-title"><span>{{assetService.schema.assetTypes[assetTypeName].name}}s</span></div> <table class="asset-group-table" cellpadding=0 cellspacing=0> <thead> <tr assess-asset-header [assetType]="assetService.schema.assetTypes[assetTypeName]"></tr> </thead> <tbody> <tr assess-asset *ngFor="#asset of assetService.assetsForType(assetTypeName)" [asset]="asset"></tr> </tbody> </table> <button class="new-asset-btn" (click)="assetService.addAsset(assetTypeName)">New</button> </div> </div>`,providers: [provide(AssetService,{useValue: injector.get(AssetService)})] }) export class AssetGroupComponent { public assetService: AssetService; public zone: NgZone; constructor( @Inject(AssetService) assetService: AssetService,zone: NgZone) { this.assetService = assetService; this.zone = zone; } ngOnInit() { this.assetService.proejectLoadedEmitter.subscribe((e) => { this.zone.run(() => { }) }); } ngOnDestroy() { this.assetService.proejectLoadedEmitter.unsubscribe(); } }
我做错了什么,或者这是我需要做什么才能更新视图?
UPDATE – AssetService类
@Injectable() export class AssetService{ public assets: Assets.Asset[] = []; public assetTypeDefinitions: any = null; public schema: Schema = null; public assetsAsObj: any = null; // Asset file loaded as object @Output() proejectLoadedEmitter: EventEmitter<any> = new EventEmitter(); constructor(){ } public loadProject(config: Project){ // Load schema // populate AssetTypeDefinitions as object keyed by type let data = fs.readFileSync(config.schemaPath,'utf8'); if (!data) { utils.logError("Error reading schema file"); return; } let struc = fs.readFileSync(config.structurePath,'utf8'); if (!struc) { utils.logError("Error reading structure file"); return; } this.schema = new Schema(JSON.parse(data),struc); this.readAssets(config.assetFilePath); } /** * @brief Adds a new asset to the assets array * @details Constructs the asset based on the type and populates * its fields with appropreiate default values * * @param type The type of the asset - specified in the schema */ public addAsset(type: string): void { // Need to make sure there is a loaded type definition for the specified type if(!this.schema.assetTypes.hasOwnProperty(type)){ utils.logError("Error occured during call to addAsset - type \"" + type + "\" is not specified in the loaded schema"); return; } // Creeate a new asset object - passing in the type definition from the schema this.assets.push(new Assets.Asset(this.schema.assetTypes[type])); } /** * Write the current assets to a file using the specified format * If the outputPasth isn't specied try and load it from the project.json file */ public writeAssets(format:AssetWriteFormat,outputPath?: string) : void { var outStructureStr = this.schema.structureStr; // insert AS properties from schema into output assets this.schema.properties.forEach(prop => { outStructureStr = outStructureStr.replace(new RegExp('"' + prop +'"','i'),this.retriveValueForSchemaProperty(prop)); }); fs.writeFileSync("C:/Projects/Assess/assets.json",outStructureStr); } public readAssets(inputPath?: string) : void{ let assetsStr = fs.readFileSync(inputPath,'utf8'); let strucToAssetMap = {}; let strucObj = JSON.parse(this.schema.structureStr); this.schema.properties.forEach(p => { strucToAssetMap[p] = this.findValueInObject(strucObj,p).reverse(); }); // @TODO Load custom properties let assetsObj = JSON.parse(assetsStr); var c = null; strucToAssetMap["AS_ASSETS"].forEach(p => { if(c == null){ c = assetsObj[p]; }else{ c = c[p]; } }); c.forEach((asset) => { let a:Assets.Asset = new Assets.Asset(this.schema.assetTypes[asset.type],asset); this.assets.push(a); }); console.log(this.assets); this.proejectLoadedEmitter.emit(null); } public assetsForType(type:string): Assets.Asset[]{ var ret: Assets.Asset[] = []; for(let idx in this.assets){ if(this.assets[idx].definition.type === type){ ret.push(this.assets[idx]); } } return ret; } public retriveValueForSchemaProperty(property: string) : string{ if(AS_SchemaTypes.indexOf(property) != -1){ switch (property) { case "AS_ASSETS": let outAssets = []; this.assets.forEach((asset) => { let outAsset = {}; outAsset["type"] = asset.definition.type; for (let key in asset.fields) { outAsset[key] = asset.fields[key].value; } outAssets.push(outAsset); }); return JSON.stringify(outAssets,null,"\t"); } }else{ // @TODO Retrive custom properties return '"DDDDDD"'; } return ""; } public findValueInObject(obj: any,property: string,path: any[] = []): any[] { for(let x in obj){; let val = obj[x]; if (val == property){ path.push(x); return path; } else if(val != null && typeof val == 'object'){ let v = this.findValueInObject(val,property,path); if(v != null){ path.push(x); return path; } } } return null; } }