Angular2 и вызов функции объекта внутри цикла в шаблоне

Сама задача несложная — раз у нас красивые структуры = объекты = наши экземпляры данных, то почему бы нам не использовать это и не заменять сложные шаблоны в выводе функциями объекта (кратко забегая наперед скажу — лучше декораторы!, но у меня получилось)

export class Record {
	id:string;
	author:string;
	date:string;
	title:string;
	text:string;
	toTestAgain() {
		return '13444';
	}
}
export class SecondResponse {
	data:Record[];
	total:number;
	code:number;
	toTest() {
		return '134';
	}
}

Как мы видим, расширить сам класс данных очень просто, и без цикла все было бы хорошо

@Component({
	...
	template: `<h1>Second Application</h1>
			<div>{{result.toTest()}}</div>
			<table *ngIf="result.data">
				<tr *ngFor="let entry of result.data">
					<td valign="top">{{entry.author}}</td>
					<td valign="top">{{entry.title}}</td>
					<td valign="top">{{entry.text}}</td>
					<td valign="top">{{entry.toTestAgain()}}</td>
				</tr>
			</table>
	`
	...
})

{{result.toTest()}} срабатывает отлично, а вот второй вызов {{entry.toTestAgain()}} — внутри перебора — нет( Пробуем вынести это все в контроллер

@Component({
	...
	template: `<h1>Second Application</h1>
			<div>{{result.toTest()}}</div>
			<table *ngIf="result.data">
				<tr *ngFor="let entry of result.data">
					<td valign="top">{{entry.author}}</td>
					<td valign="top">{{entry.title}}</td>
					<td valign="top">{{entry.text}}</td>
					<td valign="top">{{toTestAnother(entry)}}</td>
				</tr>
			</table>
 
	`
	...
})
class SecondComponent extends BasicComponent{
    ...
	public toTestAnother(entry:Record) {
		return entry.toTestAgain();
	}
}

Результат аналогичен. Виноват ли цикл?

@Component({
	...
	template: `<h1>Second Application</h1>
			<table *ngIf="result.data">
				<tr *ngFor="let entry of result.data; let i=index">
					<td valign="top">{{i}}</td>
					<td valign="top">{{entry.author}}</td>
					<td valign="top">{{entry.title}}</td>
					<td valign="top">{{entry.text}}</td>
					<td valign="top">{{toTestAnother(i)}}</td>
				</tr>
			</table>
 
	`,
	..
})
class SecondComponent extends BasicComponent{
	...
	public toTestAnother(i)	{
		return this.result.data[i].toTestAgain();
	}
	...
}

На самом деле — вопрос не в цикле, а в том что в самом объекте внутренние объекты сведены к Object

class SecondComponent extends BasicComponent{
	...
	public toTestAnother(i)	{
		console.log(this.result.data[i]);
		return '1';
	}
	...
}
...
	appService.get(this.url)
		.then(response => this.setResponse(response.json() as SecondResponse))
		.catch(appService.handleError);

response.json() as SecondResponse нам кажется что все значения будут распарсены в правильные типы — но нет! data:Record[] на самом деле data:Object[] и это наша боль и печаль. С которой можно бороться костылями

import {Component} from '@angular/core';
 
import {AppService} from './../app.service';
import {SecondResponse, Record} from './second.data';
import {BasicComponent} from "../basic/basic.component";
 
@Component({
	selector: 'my-app-second',
	template: `<h1>Second Application</h1>
			<table *ngIf="result.data">
				<tr *ngFor="let entry of result.data; let i=index">
					<td valign="top">{{i}}</td>
					<td valign="top">{{entry.author}}</td>
					<td valign="top">{{entry.title}}</td>
					<td valign="top">{{entry.text}}</td>
					<td valign="top">{{entry.toTestAgain()}}</td>
				</tr>
			</table>
 
	`,
	providers: [AppService],
})
class SecondComponent extends BasicComponent{
	public result : SecondResponse;
	constructor(public appService:AppService) {
		super(appService, 'api/second.json');
		this.result = new SecondResponse();
	}
	public setResponse(result:SecondResponse) {
		this.result = result;
		this.result.data = this.result.data.map(this.formatRecord);
	}
	formatRecord(record:Record):Record {
		let tmp = new Record();
		tmp.id = record.id;
		tmp.author = record.author;
		tmp.date = record.date;
		tmp.title = record.title;
		tmp.text = record.text;
		return tmp;
	}
}
 
export {SecondComponent};

Код выше противненький в месте где tmp.author = record.author; перебираются все поля записи — по идее там должен быть более компактный кусочек) пойду читать про тайпскрипт дальше))) Вот такой он загадочный мир ООП

Оставить комментарий

XHTML: Вы можете использовать такие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre lang="" line="" escaped="" cssfile="">