03. Компонент избранных. Локальное хранилище LocalStorage

Создание компонента из Angular CLI

В прошлом уроке мы уже создавали компонент из командной строки. Теперь мы не только создадим, но и сразу автоматически зарегистрируем компонент в основном модуле ./src/app/app.module.ts.

ng generate component favorites --module=app

Избранные друзья будут показаны списком на отдельной странице. Чтобы создать новую страницу, пропишем созданный компонент в модуле роутинга по адресу /favorites.

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { FriendsListComponent } from './friends-list/friends-list.component';
import { FriendDetailComponent } from './friend-detail/friend-detail.component';
import { FavoritesComponent } from './favorites/favorites.component';

const routes: Routes = [
	{ path: '', redirectTo: '/friends-list', pathMatch: 'full' },
	{ path: 'friends-list', component: FriendsListComponent },
	{ path: 'detail/:id', component: FriendDetailComponent },
	{ path: 'favorites', component: FavoritesComponent }
];

@NgModule({
	imports: [ RouterModule.forRoot(routes) ],
	exports: [ RouterModule ]
})

export class AppRoutingModule { }

Стилизация чекбокса

Теперь нам нужно сделать так, чтобы иметь возможность при редактировании друга пометить его избранным. Так как состояний два (избранный и не ибранный), то логично использовать чекбокс для этой цели. Переходим в ./src/app/friend-detail/friend-detail.component.html и создаём структуру для функционала добавления в избранные.

<div *ngIf="friend" class="friend-card">

	<div class="friend-card__row">
		<div class="friend-card__cell friend-card__cell_double friend-card__cell_ta-center">
			<h2>{{ friend.name }}</h2>
		</div>
	</div>
	<div class="friend-card__row">
		<div class="friend-card__cell friend-card__cell_width-40 friend-card__cell_ta-right">
			<span>ID:</span>
		</div>
		<div class="friend-card__cell friend-card__cell_width-60">
			<span>{{ friend._id }}</span>
		</div>
	</div>
	<div class="friend-card__row">
		<div class="friend-card__cell friend-card__cell_width-40 friend-card__cell_ta-right">
			<label for="friend-card__name">Имя:</label>
		</div>
		<div class="friend-card__cell friend-card__cell_width-60">
			<input id="friend-card__name" type="text" [(ngModel)]="friend.name" placeholder="Имя друга"/>
		</div>
	</div>
	<div class="friend-card__row">
		<div class="friend-card__cell friend-card__cell_width-40 friend-card__cell_ta-right">
			<div class="checkbox_fav checkbox_fav-right">
				<input id="friend-card__favorite" type="checkbox"/>
				<label for="friend-card__favorite"><i class="fa fa-heart"></i></label>
			</div>
		</div>
	</div>

</div>

Без стилизации это выглядит так:

Очевидно, что иконка сердечка вполне в состоянии визуально заменить чекбокс, нужно лишь стилизовать её отмеченное состояние. У метки (элемента label) нет состояния :checked, но спасает то, что она стоит сразу после чекбокса, а значит селектором нам послужит .checkbox_fav input[type=checkbox]:checked + label. « + » — означает следующий элемент этого же уровня. Итак, дописываем стили ./src/app/friend-detail/friend-detail.component.css:

.friend-card {
	margin:2px;
	position:relative;
	overflow:hidden;
	padding:0 0 12px 0;
}
.friend-card::before {
	display:block;
	content:"";
	position:absolute;
	top:0;
	right:0;
	bottom:0;
	left:0;
	background:#fff;
	opacity:.4;
	-webkit-box-shadow: 0 3px 15px 0 rgba(0, 0, 0, 0.75);
	-moz-box-shadow:    0 3px 15px 0 rgba(0, 0, 0, 0.75);
	box-shadow:         0 3px 15px 0 rgba(0, 0, 0, 0.75);
	z-index:1;
}
	.friend-card__row {
		position:relative;
		width:100%;
		display:flex;
		justify-content:space-between;
		z-index:2;
	}
		.friend-card__cell {
			padding:4px;
			line-height:36px;
		}
		.friend-card__cell h1,
		.friend-card__cell .h1,
		.friend-card__cell h2,
		.friend-card__cell .h2,
		.friend-card__cell h3,
		.friend-card__cell .h3 {
			margin:6px auto;
		}
		.friend-card__cell_ta-right {
			text-align:right;
		}
		.friend-card__cell_ta-center {
			text-align:center;
		}
			.friend-card__cell_ta-center h1,
			.friend-card__cell_ta-center .h1,
			.friend-card__cell_ta-center h2,
			.friend-card__cell_ta-center .h2,
			.friend-card__cell_ta-center h3,
			.friend-card__cell_ta-center .h3 {
				text-align:center;
			}
		.friend-card__cell_double {
			width:100%;
		}
		.friend-card__cell_width-40 {
			width:40%;
		}
		.friend-card__cell_width-60 {
			width:60%;
		}
		.friend-card__danger { /* Это на будущее, чтобы потом не возвращаться */
			background:#d10c31;
		}
			.checkbox_fav {
				position:relative;
				width:80px;
				height:36px;
				text-align:center;
			}
			.checkbox_fav-right {
				margin:0 0 0 auto;
				position:relative;
				left:28px;
			}
				/* Выносим чекбокс за границу видимого экрана */
				.checkbox_fav input[type=checkbox] {
				/* Чтобы не появилась горизонтальная полоса прокрутки, надо чтобы один из родителей имел overflow: hidden */
				/* Селектор .friend-card имеет такое свойство, а значит эксцессов не предвидится */
					position:absolute;
					left:-9999px;
				}
				.checkbox_fav input[type=checkbox] + label {
					opacity:.2;
					transition: opacity, color 300ms linear; /* Лёгкий способ добавить немного изящной анимации */
				}
				.checkbox_fav input[type=checkbox]:checked + label {
					color:#4ce4e4;
					opacity:1;
				}

Теперь нам необходима переменная для хранения состояния друга (избранный/не избранный). Тип Friend для этого не походит, в нём нет предусмотренного свойства для хранения этого состояния. А значит, нужно отнаследоваться от класса Friend и в новом классе создать специальное свойство для этого.

import { Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Friend } from '../friend';
import { FriendsService } from '../friends.service';
import { TransferVarsService } from '../transfer-vars.service';

export class ExtendedFriend extends Friend {
	favorite: boolean;
	constructor(fav) { 	// fav - это состояние, boolean, само собой
		super();	// некоторые версии транспилера Angular могут выдать ошибку, если мы не упомянем конструктор класса-родителя. super() - это явный вызов конструктора родителя. Вообще, в данном случае в нём особого смысла нет, т.к. мы не передаём в него каких-то переменных.
		this._id = "";
		this.index = 0;
		this.guid = "";
		this.isActive = false;
		this.balance = "";
		this.picture = "http://placehold.it/32x32";
		this.age = 0;
		this.eyeColor = "";
		this.name = "";
		this.gender = "female";
		this.company = "";
		this.email = "";
		this.phone = "";
		this.address = "";
		this.about = "";
		this.registered = "";
		this.latitude = 0;
		this.longitude = 0;
		this.tags = [];
		this.friends = [];
		this.greeting = "";
		this.favoriteFruit = "";
		this.favorite = fav; // Вот сюда конструткор нового класса будет сохранять значение при инициализации переменной класса ExtendedFriend
	}
}

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

	id: string;

	friends: Friend[];

	friend: ExtendedFriend; // Меняем тип c Friend на ExtendedFriend

	title: string = 'Редактирование';

	constructor(
		private route: ActivatedRoute,
		private friendsService: FriendsService,
		private transferVarsService: TransferVarsService
	) { }

	getFriends():void {
		this.friendsService.getFriends().subscribe(result => {
			this.friends = result;
			this.id = this.route.snapshot.paramMap.get('id');
			this.selectFriend(this.id);
		});
	}

	selectFriend(id: string):void {

		this.friend = new ExtendedFriend(false); // Инициализируем переменную

		let tempFriend = new Friend; // временное хранилище. Будет содержать ссылку на редактируемого друга

		tempFriend = this.friends.find(friend => friend._id === id);

		for (let property in tempFriend) { // копируем свойства из друга одно за одним
		// Если попытаемся передать по ссылке
		// this.friend = this.friends.find(friend => friend._id === id);
		// то транспилер скажет, что 'error, type mismatch', т.к. мы типу ExtendedFriend присваиваем значение типа Friend
			this.friend[property] = tempFriend[property]; // Поэтому копируем свойство за свойством. Переменная this.friend будет самостоятельной переменной, а не ссылкой на соответствующего друга из массива this.friends
		}

	}

	ngOnInit() {

		this.getFriends();

		this.transferVarsService.setTitle(this.title);

	}

}


Теперь мы подошли к самому главному: собственно изменению состояния и записи в LocalStorage.

Работа с window.localStorage

Отслеживать состояние хранилища приложения можно в отладчике браузера: F12 → Application → в левом меню LocalStorage.

Чтобы работать с LocalStorage, нужно его правильно подключить. На просторах stackoverflow.com мной был найден следующий способ. Открываем ./src/app/app.module.ts и заменяем код на этот (в комментариях указаны изменения):

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FriendsService } from './friends.service';
import { HttpModule } from '@angular/http';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { FriendDetailComponent } from './friend-detail/friend-detail.component';
import { FriendsListComponent } from './friends-list/friends-list.component';
import { AppRoutingModule } from './app-routing.module';
import { TransferVarsService } from './transfer-vars.service';
import { FavoritesComponent } from './favorites/favorites.component';


@NgModule({
  declarations: [
    AppComponent,
	FriendDetailComponent,
	FriendsListComponent,
	FavoritesComponent
  ],
  imports: [
    BrowserModule,
	HttpModule,
	FormsModule,
	AppRoutingModule
  ],
  providers: [FriendsService, TransferVarsService, { provide: 'LOCALSTORAGE', useFactory: getLocalStorage }], // изменения здесь
  bootstrap: [AppComponent]
})
export class AppModule { }
// изменения ниже
export function getLocalStorage() {
	return (typeof window !== "undefined") ? window.localStorage : null;
}

При помощи Inject подключим LocalStorage в ./src/app/friends-list/friend-detail.component.ts:

import { Component, Input, OnInit, Inject } from '@angular/core'; // добавляем Inject
import { ActivatedRoute } from '@angular/router';
import { Friend } from '../friend';
import { FriendsService } from '../friends.service';
import { TransferVarsService } from '../transfer-vars.service';

export class ExtendedFriend extends Friend {
	favorite: boolean;
	constructor(fav) {
		super();
		this._id = "";
		this.index = 0;
		this.guid = "";
		this.isActive = false;
		this.balance = "";
		this.picture = "http://placehold.it/32x32";
		this.age = 0;
		this.eyeColor = "";
		this.name = "";
		this.gender = "female";
		this.company = "";
		this.email = "";
		this.phone = "";
		this.address = "";
		this.about = "";
		this.registered = "";
		this.latitude = 0;
		this.longitude = 0;
		this.tags = [];
		this.friends = [];
		this.greeting = "";
		this.favoriteFruit = "";
		this.favorite = fav;
	}
}

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

	id: string;

	friends: Friend[];

	friend: ExtendedFriend;

	title: string = 'Редактирование';

	constructor(
		private route: ActivatedRoute,
		private friendsService: FriendsService,
		private transferVarsService: TransferVarsService,
		@Inject('LOCALSTORAGE') private localStorage: any // подключаем локальное хранилище как глобальную переменную компонента
	) { }

	getFriends():void {
		this.friendsService.getFriends().subscribe(result => {
			this.friends = result;
			this.id = this.route.snapshot.paramMap.get('id');
			this.selectFriend(this.id);
			this.friend.favorite = this.checkValInStorage(); // после получения списка друзей и выбора редактируемого друга ищем в локальном хранилище его текущее состояние
		});
	}

	selectFriend(id: string):void {

		this.friend = new ExtendedFriend(false);

		let tempFriend = new Friend;

		tempFriend = this.friends.find(friend => friend._id === id);

		for (let property in tempFriend) {
			this.friend[property] = tempFriend[property];
		}

	}
	
	favoriteChanging():boolean { // функция переключает состояние друга

		if ((!this.friend) || (!this.friend._id)) {
			return false;
		}

		let _id = this.friend._id;
		let fav: boolean = true;

		fav = !this.friend.favorite;

		this.locStorage(_id, fav);

	}

	locStorage(id: string, action: boolean):void { // меняет состояние в локальном хранилище

		if (action) {
			localStorage.setItem(id, 'true'); // id - ключ, в него сохраняем состояние true. Впрочем, туда можно и пустую строку сохранять, т.к. мы устанавливаем состояние просто по наличию этого ключа в хранилище
		} else {
			localStorage.removeItem(id); // если в хранлище есть такой ключ, то удаляем его, чем и достигаем переключения состояния
		}

	}

	checkValInStorage():boolean { // ищем ключ в хранилище, возвращаем true, если такой есть и он равен true

		let id: string = this.friend._id;
		let fav: string = "false";

		fav = localStorage.getItem(id);

		if (fav == "true") {return true;}
		else {return false;}

	}
	
	ngOnInit() {

		this.getFriends();

		this.transferVarsService.setTitle(this.title);

	}

}

Связываем чекбокс с логикой компонента (./src/app/friend-detail/friend-detail.component.html):

<div *ngIf="friend" class="friend-card">

	<div class="friend-card__row">
		<div class="friend-card__cell friend-card__cell_double friend-card__cell_ta-center">
			<h2>{{ friend.name }}</h2>
		</div>
	</div>
	<div class="friend-card__row">
		<div class="friend-card__cell friend-card__cell_width-40 friend-card__cell_ta-right">
			<span>ID:</span>
		</div>
		<div class="friend-card__cell friend-card__cell_width-60">
			<span>{{ friend._id }}</span>
		</div>
	</div>
	<div class="friend-card__row">
		<div class="friend-card__cell friend-card__cell_width-40 friend-card__cell_ta-right">
			<label for="friend-card__name">Имя:</label>
		</div>
		<div class="friend-card__cell friend-card__cell_width-60">
			<input id="friend-card__name" type="text" [(ngModel)]="friend.name" placeholder="Имя друга"/>
		</div>
	</div>
	<div class="friend-card__row">
		<div class="friend-card__cell friend-card__cell_width-40 friend-card__cell_ta-right">
			<div class="checkbox_fav checkbox_fav-right">
				<input id="friend-card__favorite"
				(ngModelChange)="favoriteChanging()"
				[(ngModel)]="friend.favorite" type="checkbox"/>
				<label for="friend-card__favorite"><i class="fa fa-heart"></i></label>
			</div>
		</div>
	</div>

</div>

Строка [(ngModel)]="friend.favorite" связывает компонент со свойством favorite объекта this.friend (выбранный для редактирования друг).

(ngModelChange)="favoriteChanging()" — на изменение чекбокса вызываем метод favoriteChanging, а он делает нам всю магию.

Тяжелая гифка ниже демонстрирует, что состояние сохраняется и после перезагрузки приложения.

Последние штрихи в компоненте friend-detail

Т.к. настоящая метка (label) визуально выполняет роль чекбокса, то ей нужна своя текстовая «метка». Внесём изменения в ./src/app/friend-detail/friend-detail.component.html:

<div *ngIf="friend" class="friend-card">

	<div class="friend-card__row">
		<div class="friend-card__cell friend-card__cell_double friend-card__cell_ta-center">
			<h2>{{ friend.name }}</h2>
		</div>
	</div>
	<div class="friend-card__row">
		<div class="friend-card__cell friend-card__cell_width-40 friend-card__cell_ta-right">
			<span>ID:</span>
		</div>
		<div class="friend-card__cell friend-card__cell_width-60">
			<span>{{ friend._id }}</span>
		</div>
	</div>
	<div class="friend-card__row">
		<div class="friend-card__cell friend-card__cell_width-40 friend-card__cell_ta-right">
			<label for="friend-card__name">Имя:</label>
		</div>
		<div class="friend-card__cell friend-card__cell_width-60">
			<input id="friend-card__name" type="text" [(ngModel)]="friend.name" placeholder="Имя друга"/>
		</div>
	</div>
	<div class="friend-card__row">
		<div class="friend-card__cell friend-card__cell_width-40 friend-card__cell_ta-right">
			<div class="checkbox_fav checkbox_fav-right">
				<input id="friend-card__favorite" (ngModelChange)="favoriteChanging()" [(ngModel)]="friend.favorite" type="checkbox"/>
				<label for="friend-card__favorite"><i class="fa fa-heart"></i></label>
			</div>
		</div>
		<div class="friend-card__cell friend-card__cell_width-60">
			<label *ngIf="friend.gender == 'female'" for="friend-card__favorite">избранная</label>
			<label *ngIf="friend.gender == 'male'" for="friend-card__favorite">избранный</label>
		</div>
	</div>

</div>

Теперь в зависимости от пола друга рядом с его именем будет стоять слово «избранный» или «избранная».

Результирующие листинги изменённых файлов

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FriendsService } from './friends.service';
import { HttpModule } from '@angular/http';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { FriendDetailComponent } from './friend-detail/friend-detail.component';
import { FriendsListComponent } from './friends-list/friends-list.component';
import { AppRoutingModule } from './app-routing.module';
import { TransferVarsService } from './transfer-vars.service';
import { FavoritesComponent } from './favorites/favorites.component';


@NgModule({
  declarations: [
    AppComponent,
	FriendDetailComponent,
	FriendsListComponent,
	FavoritesComponent
  ],
  imports: [
    BrowserModule,
	HttpModule,
	FormsModule,
	AppRoutingModule
  ],
  providers: [FriendsService, TransferVarsService, { provide: 'LOCALSTORAGE', useFactory: getLocalStorage }],
  bootstrap: [AppComponent]
})
export class AppModule { }

export function getLocalStorage() {
	return (typeof window !== "undefined") ? window.localStorage : null;
}

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { FriendsListComponent } from './friends-list/friends-list.component';
import { FriendDetailComponent } from './friend-detail/friend-detail.component';
import { FavoritesComponent } from './favorites/favorites.component';

const routes: Routes = [
	{ path: '', redirectTo: '/friends-list', pathMatch: 'full' },
	{ path: 'friends-list', component: FriendsListComponent },
	{ path: 'detail/:id', component: FriendDetailComponent },
	{ path: 'favorites', component: FavoritesComponent }
];

@NgModule({
	imports: [ RouterModule.forRoot(routes) ],
	exports: [ RouterModule ]
})

export class AppRoutingModule { }

<div *ngIf="friend" class="friend-card">

	<div class="friend-card__row">
		<div class="friend-card__cell friend-card__cell_double friend-card__cell_ta-center">
			<h2>{{ friend.name }}</h2>
		</div>
	</div>
	<div class="friend-card__row">
		<div class="friend-card__cell friend-card__cell_width-40 friend-card__cell_ta-right">
			<span>ID:</span>
		</div>
		<div class="friend-card__cell friend-card__cell_width-60">
			<span>{{ friend._id }}</span>
		</div>
	</div>
	<div class="friend-card__row">
		<div class="friend-card__cell friend-card__cell_width-40 friend-card__cell_ta-right">
			<label for="friend-card__name">Имя:</label>
		</div>
		<div class="friend-card__cell friend-card__cell_width-60">
			<input id="friend-card__name" type="text" [(ngModel)]="friend.name" placeholder="Имя друга"/>
		</div>
	</div>
	<div class="friend-card__row">
		<div class="friend-card__cell friend-card__cell_width-40 friend-card__cell_ta-right">
			<div class="checkbox_fav checkbox_fav-right">
				<input id="friend-card__favorite" (ngModelChange)="favoriteChanging()" [(ngModel)]="friend.favorite" type="checkbox"/>
				<label for="friend-card__favorite"><i class="fa fa-heart"></i></label>
			</div>
		</div>
		<div class="friend-card__cell friend-card__cell_width-60">
			<label *ngIf="friend.gender == 'female'" for="friend-card__favorite">избранная</label>
			<label *ngIf="friend.gender == 'male'" for="friend-card__favorite">избранный</label>
		</div>
	</div>

</div>

.friend-card {
	margin:2px;
	position:relative;
	overflow:hidden;
	padding:0 0 12px 0;
}
.friend-card::before {
	display:block;
	content:"";
	position:absolute;
	top:0;
	right:0;
	bottom:0;
	left:0;
	background:#fff;
	opacity:.4;
	-webkit-box-shadow: 0 3px 15px 0 rgba(0, 0, 0, 0.75);
	-moz-box-shadow:    0 3px 15px 0 rgba(0, 0, 0, 0.75);
	box-shadow:         0 3px 15px 0 rgba(0, 0, 0, 0.75);
	z-index:1;
}
	.friend-card__row {
		position:relative;
		width:100%;
		display:flex;
		justify-content:space-between;
		z-index:2;
	}
		.friend-card__cell {
			padding:4px;
			line-height:36px;
		}
		.friend-card__cell h1,
		.friend-card__cell .h1,
		.friend-card__cell h2,
		.friend-card__cell .h2,
		.friend-card__cell h3,
		.friend-card__cell .h3 {
			margin:6px auto;
		}
		.friend-card__cell_ta-right {
			text-align:right;
		}
		.friend-card__cell_ta-center {
			text-align:center;
		}
			.friend-card__cell_ta-center h1,
			.friend-card__cell_ta-center .h1,
			.friend-card__cell_ta-center h2,
			.friend-card__cell_ta-center .h2,
			.friend-card__cell_ta-center h3,
			.friend-card__cell_ta-center .h3 {
				text-align:center;
			}
		.friend-card__cell_double {
			width:100%;
		}
		.friend-card__cell_width-40 {
			width:40%;
		}
		.friend-card__cell_width-60 {
			width:60%;
		}
		.friend-card__danger {
			background:#d10c31;
		}
			.checkbox_fav {
				position:relative;
				width:80px;
				height:36px;
				text-align:center;
			}
			.checkbox_fav-right {
				margin:0 0 0 auto;
				position:relative;
				left:28px;
			}
				.checkbox_fav input[type=checkbox] {
					position:absolute;
					left:-9999px;
				}
				.checkbox_fav input[type=checkbox] + label {
					opacity:.2;
					transition: opacity, color 300ms linear;
				}
				.checkbox_fav input[type=checkbox]:checked + label {
					color:#4ce4e4;
					opacity:1;
				}

import { Component, Input, OnInit, Inject } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Friend } from '../friend';
import { FriendsService } from '../friends.service';
import { TransferVarsService } from '../transfer-vars.service';

export class ExtendedFriend extends Friend {
	favorite: boolean;
	constructor(fav) {
		super();
		this._id = "";
		this.index = 0;
		this.guid = "";
		this.isActive = false;
		this.balance = "";
		this.picture = "http://placehold.it/32x32";
		this.age = 0;
		this.eyeColor = "";
		this.name = "";
		this.gender = "female";
		this.company = "";
		this.email = "";
		this.phone = "";
		this.address = "";
		this.about = "";
		this.registered = "";
		this.latitude = 0;
		this.longitude = 0;
		this.tags = [];
		this.friends = [];
		this.greeting = "";
		this.favoriteFruit = "";
		this.favorite = fav;
	}
}

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

	id: string;

	friends: Friend[];

	friend: ExtendedFriend;

	title: string = 'Редактирование';

	constructor(
		private route: ActivatedRoute,
		private friendsService: FriendsService,
		private transferVarsService: TransferVarsService,
		@Inject('LOCALSTORAGE') private localStorage: any
	) { }

	getFriends():void {
		this.friendsService.getFriends().subscribe(result => {
			this.friends = result;
			this.id = this.route.snapshot.paramMap.get('id');
			this.selectFriend(this.id);
			this.friend.favorite = this.checkValInStorage();
		});
	}

	selectFriend(id: string):void {

		this.friend = new ExtendedFriend(false);

		let tempFriend = new Friend;

		tempFriend = this.friends.find(friend => friend._id === id);

		for (let property in tempFriend) {
			this.friend[property] = tempFriend[property];
		}

	}
	
	favoriteChanging():boolean {

		if ((!this.friend) || (!this.friend._id)) {
			return false;
		}

		let _id = this.friend._id;
		let fav: boolean = true;

		fav = !this.friend.favorite;

		this.locStorage(_id, fav);

	}

	locStorage(id: string, action: boolean):void {

		if (action) {
			localStorage.setItem(id, 'true');
		} else {
			localStorage.removeItem(id);
		}

	}

	checkValInStorage():boolean {

		let id: string = this.friend._id;
		let fav: string = "false";

		fav = localStorage.getItem(id);

		if (fav == "true") {return true;}
		else {return false;}

	}
	
	ngOnInit() {

		this.getFriends();

		this.transferVarsService.setTitle(this.title);

	}

}


Дополнительные ссылки