NgFor в веб-компоненте Angular Elements Использование файла JSON: как получить значения - PullRequest
1 голос
/ 02 ноября 2019

РЕДАКТИРОВАТЬ: это веб-компонент в статическом файле HTML, я использую только Angular для его компиляции.

Я экспериментирую с Angular Elements и создал веб-компонент, которыйпростой NgFor с входом из файла JSON.

<div *ngFor="let name of names | keyvalue" (click)="onClick(name)">
{{name.value | json}}
</div

JSON

[ 
{  
    "id":1,
    "name": "star 1",
    "image":"https://picsum.photos/id/1059/400/400",
    "text":"Text about star 1"
},
{  
    "id":2,
    "name": "star 2",
    "image":"https://picsum.photos/id/1060/400/400",
    "text":"Text about star 2"
},
{  
    "id":3,
    "name": "star 3",
    "image":"https://picsum.photos/id/1061/400/400",
    "text":"Text about star 3"
},
{  
    "id":4,
    "name": "star 4",
    "image":"https://picsum.photos/id/1062/400/400",
    "text":"Text about star 4"
},
{  
    "id":5,
    "name": "star 5",
    "image":"https://picsum.photos/id/1063/400/400",
    "text":"Text about star 5"
},
{  
    "id":6,
    "name": "star 6",
    "image":"https://picsum.photos/id/1064/400/400",
    "text":"Text about star 6"
},
{  
    "id":7,
    "name": "star 7",
    "image":"https://picsum.photos/id/1065/400/400",
    "text":"Text about star 7"
},
{  
    "id":8,
    "name": "star 8",
    "image":"https://picsum.photos/id/1066/400/400",
    "text":"Text about star 8"
},
{  
    "id":9,
    "name": "star 9",
    "image":"https://picsum.photos/id/1067/400/400",
    "text":"Text about star 9"
},
{  
    "id":10,
    "name": "star 10",
    "image":"https://picsum.photos/id/1068/400/400",
    "text":"Text about star 10"
}
]

Это выводит в браузере

  { "id": 1, "name": "star 1", "image": "https://picsum.photos/id/1059/400/400", "text": "Text about star 1" }
  { "id": 2, "name": "star 2", "image": "https://picsum.photos/id/1060/400/400", "text": "Text about star 2" }
  { "id": 3, "name": "star 3", "image": "https://picsum.photos/id/1061/400/400", "text": "Text about star 3" }
  { "id": 4, "name": "star 4", "image": "https://picsum.photos/id/1062/400/400", "text": "Text about star 4" }
  { "id": 5, "name": "star 5", "image": "https://picsum.photos/id/1063/400/400", "text": "Text about star 5" }
  { "id": 6, "name": "star 6", "image": "https://picsum.photos/id/1064/400/400", "text": "Text about star 6" }
  { "id": 7, "name": "star 7", "image": "https://picsum.photos/id/1065/400/400", "text": "Text about star 7" }
  { "id": 8, "name": "star 8", "image": "https://picsum.photos/id/1066/400/400", "text": "Text about star 8" }
  { "id": 9, "name": "star 9", "image": "https://picsum.photos/id/1067/400/400", "text": "Text about star 9" }
  { "id": 10, "name": "star 10", "image": "https://picsum.photos/id/1068/400/400", "text": "Text about star 10" }

Что я хочу сделатьдоступ к свойствам в этом объекте, поэтому, когда я нажимаю на одно из них, он обновляет img src другого элемента с источником в значении изображения.

Если я вернусь к шаблону и попытаюсь использовать {{name.value.image}} Я получаю сообщение об ошибке:

Свойство 'image' не существует для типа 'string'.

Как получить доступ к значению изображения в этом объекте, чтобыЯ могу использовать его в другом месте?

Пожалуйста, имейте в виду, что я компилирую это с Angular Elements и использую его на статической html-странице. Спасибо

Ответы [ 3 ]

1 голос
/ 02 ноября 2019

Поскольку names - это массив объектов, вам не нужно использовать keyvalue здесь.

Попробуйте вот так:

<div *ngFor="let name of names" (click)="onClick(name)">
    {{name.image}}
</div>
0 голосов
/ 03 ноября 2019

ОК, так что я понял, что я делаю не так. Поскольку это веб-компонент и любая строка или объект могут быть переданы через свойство html, я не могу знать, какими будут имена свойств при компиляции компонента в angular. Так что names.anything приведет к ошибке при компиляции.

Решением было испустить весь объект через @Output, добавить обработчик событий в html-скрипт, а затем выбрать свойство из объекта события. Надеюсь, что из приведенного ниже станет ясно, чего я пытался достичь и почему у меня возникли проблемы. <name-list/> - это имя моего веб-компонента, которое за кадром выглядит как <name-list names="{object}"/>

<name-list />
<img></img>
<script src="elementCommunicationWithDom.js"></script>// this is the compiled Angular elements file
<script>
    init();
    function loadJSON(callback) {   //needed to access local JSON file

        var xobj = new XMLHttpRequest();
        xobj.overrideMimeType("application/json");
        xobj.open('GET', 'data.json', true);
        xobj.onreadystatechange = function () {
            if (xobj.readyState == 4 && xobj.status == "200") {
                callback(xobj.responseText);
            }
        };
        xobj.send(null);
    }

    function init() {
        loadJSON(function (response) {
            var obj = JSON.parse(response);
            let element = document.querySelector('name-list');
            element.names = obj; //set the html property names created in @input in Angular to the object
        });
    }

    let element = document.querySelector('name-list');
    let img = document.querySelector('img');
    element.addEventListener("onSelectItem", (event) => { //gets the output of @Output which is onSelectItem
        img.src = event.detail.image;
        console.log(event.detail.image)
    })

</script>
0 голосов
/ 02 ноября 2019

Я думаю, вам нужно что-то вроде этого:

component.ts:

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
public names = [ 
{  
    "id":1,
    "name": "star 1",
    "image":"https://picsum.photos/id/1059/400/400",
    "text":"Text about star 1"
},
{  
    "id":2,
    "name": "star 2",
    "image":"https://picsum.photos/id/1060/400/400",
    "text":"Text about star 2"
},
{  
    "id":3,
    "name": "star 3",
    "image":"https://picsum.photos/id/1061/400/400",
    "text":"Text about star 3"
},
{  
    "id":4,
    "name": "star 4",
    "image":"https://picsum.photos/id/1062/400/400",
    "text":"Text about star 4"
},
{  
    "id":5,
    "name": "star 5",
    "image":"https://picsum.photos/id/1063/400/400",
    "text":"Text about star 5"
},
{  
    "id":6,
    "name": "star 6",
    "image":"https://picsum.photos/id/1064/400/400",
    "text":"Text about star 6"
},
{  
    "id":7,
    "name": "star 7",
    "image":"https://picsum.photos/id/1065/400/400",
    "text":"Text about star 7"
},
{  
    "id":8,
    "name": "star 8",
    "image":"https://picsum.photos/id/1066/400/400",
    "text":"Text about star 8"
},
{  
    "id":9,
    "name": "star 9",
    "image":"https://picsum.photos/id/1067/400/400",
    "text":"Text about star 9"
},
{  
    "id":10,
    "name": "star 10",
    "image":"https://picsum.photos/id/1068/400/400",
    "text":"Text about star 10"
}
];


public imgSrc = '';

public setSource(name) {
  this.imgSrc = name.image;
}
}

и HTML:

<div *ngFor="let name of names" (click)="setSource(name)">
{{name.image | json}}
</div>

<img [src]="imgSrc" >

...