0

コンポーネント テンプレートで使用して div の背景画像を設定するには、サニタイズされた 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;
        }
    )
4

1 に答える 1

2

サブスクライブ関数は非同期であるため、サブスクライブ関数が実行される前にマップ関数が呼び出されます。したがって、このフェーズでは、初期値を設定しないため、配列は未定義です。

解決策は、サブスクライブ関数内でこれを行い、アイテムを空の配列で初期化することです。

 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)"))}
    });

}
于 2016-10-27T11:10:24.253 に答える