Typescript 角度2-为什么我需要zone.run()?
我正在尝试在Angular 2中创建一个组件,它显示来自服务的数据。该服务基本上是在用户输入一些数据后从json文件加载一些数据。我一直试图让组件更新,但它似乎无法识别更改,除非我在从我的服务提交事件后调用zone.run()。我的组件代码如下所示Typescript 角度2-为什么我需要zone.run()?,typescript,angular,Typescript,Angular,我正在尝试在Angular 2中创建一个组件,它显示来自服务的数据。该服务基本上是在用户输入一些数据后从json文件加载一些数据。我一直试图让组件更新,但它似乎无法识别更改,除非我在从我的服务提交事件后调用zone.run()。我的组件代码如下所示 @Component({ selector: 'assess-asset-group', directives: [AssetComponent, AssetHeaderComponent, NgFor, NgIf], tem
@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();
}
}
@组件({
选择器:“评估资产组”,
指令:[资产组件、资产组件、NgFor、NgIf],
模板:`
{{assetService.schema.assetTypes[assetTypeName].name}}s
新的
`,
提供者:[提供(AssetService,{useValue:injector.get(AssetService)}]
})
导出类AssetGroupComponent{
公共资产服务:资产服务;
公共区域:NgZone;
构造函数(@Inject(AssetService)AssetService:AssetService,区域:NgZone){
this.assetService=assetService;
这个区域=区域;
}
恩戈尼尼特(){
this.assetService.proejectLoadedEmitter.subscribe((e)=>{this.zone.run(()=>{}));
}
恩贡德斯特罗(){
this.assetService.proejectLoadedEmitter.unsubscribe();
}
}
我是做错了什么,还是为了更新视图,我需要这样做
更新-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;
}
}
@Injectable()
导出类资产服务{
公共资产:资产。资产[]=[];
公共资产类型定义:any=null;
公共模式:schema=null;
public assetsabj:any=null;//作为对象加载的资产文件
@Output()proejectLoadedEmitter:EventEmitter=新的EventEmitter();
构造函数(){
}
公共加载项目(配置:项目){
//加载模式
//将AssetTypeDefinitions填充为按类型键入的对象
让data=fs.readFileSync(config.schemaPath,'utf8');
如果(!数据){
logError(“读取模式文件时出错”);
返回;
}
让struc=fs.readFileSync(config.structurePath,'utf8');
如果(!struc){
utils.logError(“读取结构文件时出错”);
返回;
}
this.schema=newschema(JSON.parse(data),struc);
this.readAssets(config.assetFilePath);
}
/**
*@brief将新资源添加到资源数组中
*@details根据类型构造资产并填充
*其字段具有适当的默认值
*
*@param type在架构中指定的资产类型
*/
public addAsset(类型:string):void{
//需要确保指定类型有已加载的类型定义
如果(!this.schema.assetTypes.hasOwnProperty(类型)){
logError(“调用addAsset时发生错误-加载的架构中未指定类型\”+type+“\”);
返回;
}
//创建一个新的资产对象-从模式中传入类型定义
this.assets.push(newassets.Asset(this.schema.assetTypes[type]);
}
/**
*使用指定格式将当前资源写入文件
*如果outputPasth未指定,请尝试从project.json文件加载它
*/
公共writeAssets(格式:AssetWriteFormat,outputPath?:字符串):无效{
var outStructureStr=this.schema.structureStr;
//将作为属性从架构插入到输出资产中
this.schema.properties.forEach(prop=>{
outStructureStr=outStructureStr.replace(新的RegExp(““+prop+”,“i”),this.retrievValueforSchemaProperty(prop));
});
fs.writeFileSync(“C:/Projects/assessment/assets.json”,outStructureStr);
}
公共读取资产(inputPath?:字符串):无效{
让assetsStr=fs.readFileSync(inputPath,'utf8');
设strucToAssetMap={};
让strucObj=JSON.parse(this.schema.structureStr);
this.schema.properties.forEach(p=>{
strucToAssetMap[p]=this.findValueInObject(strucObj,p).reverse();
});
//@TODO加载自定义属性
让assetsObj=JSON.parse(assetsStr);
var c=null;
strucToAssetMap[“作为资产”].forEach(p=>{
如果(c==null){
c=资产目标[p];
}否则{
c=c[p];
}
});
c、 forEach((资产)=>{
设a:Assets.Asset=new Assets.Asset(this.schema.assetTypes[Asset.type],Asset);
本.资产.推送(a);
});
console.log(this.assets);
this.proejectLoadedEmitter.emit(null);
}
public assetsForType(类型:string):Assets.Asset[]{
var ret:Assets.Asset[]=[];
for(让idx在这个.assets中){
if(this.assets[idx].definition.type==type){
ret.push(本资产[idx]);
}
}
返回ret;
}
public RetrieveValueForSchemaProperty(属性:string):string{
if(作为SchemaTypes.indexOf(属性)!=-1){
交换机(属性){
案例“作为资产”:
出租资产=[];
this.assets.forEach((资产)=>{
让outAsset={};
outAsset[“类型”]=asset.definition.type;
for(输入asset.fields){
outAsset[key]=资产。字段[key]。值;
}
outAsset.push(outAsset);
});
返回JSON.stringify(outAssets,null,“\t”);
}
}否则{
//@TODO检索自定义属性
返回“dddd”;
}
返回“”;
}
public findValueInObject(对象:任意,属性:st