2016-10-26 18 views
0

我需要生成与我的组件模板的设置div的背景图像消毒CSS属性指定的模板使用方法:使用数据获得我怎样才能消毒CSS属性从数据服务

<div *ngFor="let Item of Items" 
    [style.background-image]="Item.imageStyle 
    (click)="gotoDetail(Item.iditems)"> 
</div> 

通过数据服务。该组件是:

import { Component } from '@angular/core'; 
    import { Router } from '@angular/router'; 
    import { DomSanitizer } from '@angular/platform-browser'; 
    import { OnInit } from '@angular/core'; 

    import { Item } from '../models/Item'; 

    import { CollectionDataService } from '../services/CollectionData.service'; 

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

    Items: Item[]; 

    ngOnInit() { 

     this.collectionDataService.getItems().subscribe(
       Items => this.Items = Items 
      ); 

     // Generates and sanitizes image links 
     this.Items.map(
       (LItem) => LItem.imageStyle = this.sanitizer.bypassSecurityTrustStyle("url(template/images/"+LItem.iditems+".jpg)") 
      ) 
    } 

    constructor(
      private router: Router, 
      private sanitizer: DomSanitizer, 
      private collectionDataService: CollectionDataService 
     ) { 

    } 

    gotoDetail($iditems: number): void { 
     this.router.navigate(['/viewer', $iditems]); 
    } 
    } 

但它不起作用,因为产生的消毒性能

this.Items.map(
       (LItem) => LItem.imageStyle = this.sanitizer.bypassSecurityTrustStyle("url(template/images/"+LItem.iditems+".jpg)") 
      ) 

声明没有找到加载的数据。那我看到在浏览器控制台的错误是:

core.umd.js:3070 EXCEPTION: Uncaught (in promise): Error: Error in ./MainpageComponent class MainpageComponent_Host - inline template:0:0 caused by: Cannot read property 'map' of undefined 
TypeError: Cannot read property 'map' of undefined 

数据服务是:

import { Injectable } from '@angular/core' 
    import { Http } from '@angular/http' 
    import { Item } from '../models/Item'; 
    import { DomSanitizer } from '@angular/platform-browser'; 

    @Injectable() 
    export class CollectionDataService { 

    constructor(
      private http: Http, 
      private sanitizer: DomSanitizer 
     ) { } 

    getItems() { 

     return this.http.get('app/mocksdata/items.json').map(
        response => <Item[]>response.json().items 
      ) 

    } 

    } 

和所提供的items.json:

{ 
    "items": [{ 
      "iditems": 1, 
      "imageStyle": "" 
     }, { 
      "iditems": 2, 
      "imageStyle": "" 
     }] 
    } 

如果我设置静态数据在组件中,而不是使用数据服务,一切正常:

export class MainpageComponent implements OnInit { 

    Items: Item[]; 

    ngOnInit() { 

     this.Items = [{ 
      "iditems": 1, 
      "imageStyle": "" 
     }, { 
      "iditems": 2, 
      "imageStyle": "" 
     }] 

     // Generates and sanitizes image links 
     this.Items.map(
       (LItem) => LItem.imageStyle = this.sanitizer.bypassSecurityTrustStyle("url(template/images/"+LItem.iditems+".jpg)") 
      ) 
    } 

如何强制清理程序语句等待异步数据完全加载?或者,我怎样才能直接在服务中生成清理过的属性?

编辑 最好的答案来自PatrickJane如下:

 Items: Item[] = []; 

     ngOnInit() { 

     this.collectionDataService.getItems().subscribe(Items => { 
      this.Items = Items; 
      this.Items.map(LItem => LItem.imageStyle = this.sanitizer.bypassSecurityTrustStyle("url(template/images/"+LItem.iditems+".jpg)"))} 
     }); 

    } 

我也解决了这个问题,直接在服务方法(credits)工作,但它是更冗长:

return this.http.get('app/mocksdata/items.json') 
    .map((responseData) => { 
      return responseData.json().items; 
     }) 
    .map(
     (iitems: Array<any>) => { 
      let result:Array<Item> = []; 
      if (iitems) { 
       iitems.forEach((iitem) => { 
        iitem.imageStyle = this.sanitizer.bypassSecurityTrustStyle("url(template/images/"+iitem.iditems+".jpg)"); 
        result.push(<Item>iitem); 
       }); 
      } 
      return result; 
     } 
    ) 

回答

2

订阅函数是异步的,因此您的映射函数在订阅函数运行之前调用。所以在这个阶段,数组是没有定义的,因为你没有设置任何初始值。

解决方法是在subscribe函数中执行此操作,并使用空数组初始化Items。

Items: Item[] = []; 

ngOnInit() { 

    this.collectionDataService.getItems().subscribe(Items => { 
     this.Items = Items; 
     this.Items.map(LItem => LItem.imageStyle = this.sanitizer.bypassSecurityTrustStyle("url(template/images/"+LItem.iditems+".jpg)"))} 
    }); 

} 
+0

谢谢你的回答:它的工作原理。我也试着直接在服务方法中管理这个,但是你的解决方案更清洁。 –