Случайны выбор дневника Раскрыть/свернуть полный список возможностей


Найдено 3269 сообщений
Cообщения с меткой

tutorial - Самое интересное в блогах

Следующие 30  »
anisimowa_tata

Наборный ряд с фестонами - gaanna.ru

Пятница, 20 Мая 2016 г. 16:20 (ссылка)
gaanna.ru/page/nabornyj-rjad-s-festonami

Наборный ряд с фестонами немного эластичнее цепочки из воздушных петель. Главное достоинство такого наборного края то, что он является одновременно и отделкой детали.
Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
pussy-cats

Эластичный набор петель для вязания полой итальянской резинки от Натальи Кошельковой (спицами)

Четверг, 19 Мая 2016 г. 12:36 (ссылка)


Эластичный набор петель для вязания полой итальянской резинки от Натальи Кошельковой.


https://youtu.be/z3edfq,qHd9w


Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
pussy-cats

Использование накидов для аккуратного вязания кос и др. аранов (спицами)

Четверг, 19 Мая 2016 г. 11:53 (ссылка)


Этим приёмом поделилась замечательная мастерица Леся (less) на форуме osinka.ru



Чтобы получить красивые косы или араны, нужно делать накид в месте скрещивания кос в изнаночном ряду, предшествующем скрещиванию.



Подробности
Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
tango123

Наборный ряд с фестонами - gaanna.ru

Среда, 18 Мая 2016 г. 17:39 (ссылка)
gaanna.ru/page/nabornyj-rjad-s-festonami


Наборный ряд с фестонами немного эластичнее цепочки из воздушных петель. Главное достоинство такого наборного края то, что он является одновременно и отделкой детали.

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

[Перевод] Angular 2 Beta, обучающий курс «Тур героев» часть 4

Суббота, 14 Мая 2016 г. 17:41 (ссылка)

Часть 1 Часть 2 Часть 3 Часть 4



Сервисы



Тур героев развивается, и мы ожидаем добавление новых компонентов в ближайшем будущем.



Нескольким компонентам нужен доступ к данным героев, и мы не хотим копировать и вставлять один и тот же код снова и снова. Вместо этого мы создадим один сервис передачи данных, который можно будет в дальнейшем повторно использовать, и научимся использовать его в компонентах, которые в нем нуждаются.



Рефакторинг доступа к данным в отдельный сервис помогает не "раздувать" компоненты и направлен на поддержку отображения. Кроме того, использование мок-сервиса (мок — заглушка, позволяет не обращаться к реальным данным с сервера) облегчает модульное тестирование компонента (unit-тесты).



Поскольку данные, получаемые сервисом всегда будут асинхронными, мы закончим эту главу версией сервиса, основанной на обещания (промисах, promise).



Запустить приложение, часть 4



Где мы остановились



Прежде чем продолжить наш Тур героев, давайте проверим, что наш проект имеет следующую структуру. Если это не так, нужно будет вернуться к предыдущим главам.



    angular2-tour-of-heroes
app
app.component.ts
hero.ts
hero-detail.component.ts
main.ts
node_modules ...
typings ...
index.html
package.json
styles.css
systemjs.config.js
tsconfig.json
typings.json


Поддержка преобразования кода и выполнения приложения



Откройте окно терминала / консоли. Запустите компилятор TypeScript, который будет следить за изменениями, и сервер, введя команду:



    npm start


Приложение запустится и будет обновляться автоматически, пока мы будем создавать Тур героев.



Создание сервиса героев



Наши заказчики поделились своим видением нашего приложения. Они говорят, что хотят отображать героев по-разному на разных страницах. Мы уже можем выбрать героя из списка. Скоро мы добавим панель для отображения самых лучших героев, и создадим отдельное представление для редактирования деталей героя. Всем этим представлениям нужны данные героев.



В данный момент AppComponent содержит фиктивные данные героев. У нас есть как минимум два возражения. Во-первых, определение данных героев не является обязанностью компонента. Во-вторых, мы не можем легко предоставить доступ к этим данным другим компонентам и представлениям.



Мы можем отрефакторить логику получения данных о героях в один сервис, который будет предоставлять доступ к данным о героях и дать доступ к этому сервису тем компонентам, которым нужны герои.



Создание HeroService



Создайте файл в папке app с именем hero.service.ts.



Мы приняли конвенцию, в которой сервис именуется буквами в нижнем регистре с добавлением .service. Если имя сервиса состоит из нескольких слов, для именования используется "нижний регистр с тире". Например, сервис SpecialSuperHeroService будет определен именем файла special-super-hero.service.ts.


Назовем класс HeroService и пометим его экспортируемым, чтобы другие классы могли его импортировать.



hero.service.ts (экспортированный класс)



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

@Injectable()
export class HeroService {
}


Внедрение сервиса



Обратите внимание на то, что мы импортировали функцию Angular Injectable и использовали декоратор @Injectable().



Не забудьте круглые скобки! Их игнорирование приводит к трудно диагностируемой ошибке.


TypeScript видит декоратор @Injectable() и делает доступными метаданные о нашем сервисе, те метаданные, которые Angular возможно потребуется внедрить в другие зависимости этого сервиса.



В данный момент HeroService не имеет никаких зависимостей. Добавьте декоратор в любом случае. Это пример "best practice" (хорошей практики) — применить декоратор @Injectable() с самого начала, чтобы показать его предназначение в перспективе.



Получение героев


Добавим метод-заглушку getHeroes.



hero.service.ts (заглушка getHeroes)



    @Injectable()
export class HeroService {
getHeroes() {
}
}


Немного повременим с реализацией, чтобы сделать важное замечание.



Потребитель нашего сервиса не знает, каким образом сервис получает данные. Наш HeroService может получить данные Hero отовсюду. Он мог бы получить данные из веб-сервиса или локального запоминающего устройства или из мок-метода, возвращающего некие фиктивные данные.



В этом прелесть вынесения доступа к данным из компонента. Мы можем менять реализации так часто, как нам нравится и когда это потребуется, не затрагивая компоненты, которые нуждаются в данных о героях.



Фиктивные данные героев


У нас уже есть фиктивные данные Hero, которые находятся в AppComponent. Но здесь им не место. Мы переместим эти фиктивные данные в отдельный файл.



Вырежем массив HEROES из app.component.ts и вставим его в новый файл в папке app с названием heroes.ts. Кроме того, нужно скопировать объявление import {Hero} ..., потому что массив героев использует класс Hero.



mock-heroes.ts (Массив героев)



    import { Hero } from './hero';
export var HEROES: Hero[] = [
{"id": 11, "name": "Mr. Nice"},
{"id": 12, "name": "Narco"},
{"id": 13, "name": "Bombasto"},
{"id": 14, "name": "Celeritas"},
{"id": 15, "name": "Magneta"},
{"id": 16, "name": "RubberMan"},
{"id": 17, "name": "Dynama"},
{"id": 18, "name": "Dr IQ"},
{"id": 19, "name": "Magma"},
{"id": 20, "name": "Tornado"}
];


Мы экспортируем массив HEROES как константу, поэтому мы можем импортировать его в другом месте — например, как наш HeroService.



Тем временем, в app.component.ts, откуда мы вырезали массив HEROES, мы оставляем неинициализированное свойство heroes:



app.component.ts (свойство heroes)



    heroes: Hero[];


Возвращение фиктивного списка героев


Вернувшись в HeroService мы импортируем нашу заглушку HEROES и возвращаем ее в методе getHeroes. Наш сервис HeroService выглядит следующим образом:



hero.service.ts



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

import { HEROES } from './mock-heroes';

@Injectable()
export class HeroService {
getHeroes() {
return HEROES;
}
}


Использование сервиса героев


Мы готовы использовать HeroService в других компонентах. Начнем с AppComponent.



В начале, как обычно, импортируем то, что хотим использовать, то есть HeroService.



app.component.ts (import HeroService)



    import { HeroService } from './hero.service';


Импорт сервиса позволяет ссылаться на него в нашем коде. Как AppComponent должен получить конкретный экземпляр HeroService во время выполнения?



Должны ли мы использовать new HeroService? Ни в коем случае!


Мы могли бы создать новый экземпляр HeroService, используя new, например, вот так (не надо так делать!):



    heroService = new HeroService(); // don't do this


Это плохая идея по нескольким причинам.




  • Наш компонент должен знать, как создать HeroService. Если мы когда-нибудь изменим конструктор HeroService, мы должны найти каждое место, в котором создается сервис и внести правки. Такие правки могут привести к появлению ошибок, и добавляют дополнительную нагрузку по тестированию.

  • Мы создаем новый сервис каждый раз, когда мы используем "new". Что делать, если сервис должен кэшировать героев и обмениваться кэшем с другими? Мы не сможем сделать это.

  • В AppComponent мы привязываемся к конкретной реализации HeroService. Будет трудно переключать реализации для различных сценариев. Можем ли мы работать оффлайн? Нужны ли будут разные версии фиктивных реализаций при тестировании? Это не просто.



Что, если… что, если… Эй, у нас есть работа, которую нужно сделать!



Мы сделаем это. Избежать этих проблем так легко, что нет никаких оправданий для того, чтобы сделать это неправильно.



Внедрение HeroService


Две строки вместо одной, использовавшей new:




  1. Мы добавим конструктор.

  2. Мы добавим метаданные providers в компонент.



Вот конструктор:



app.component.ts (конструктор)



    constructor(private heroService: HeroService) { }


Сам по себе конструктор ничего не делает. Параметр одновременно определяет приватное свойство heroService и идентифицирует его как место внедрения HeroService.



Теперь Angular будет знать, чтобы необходимо передать экземпляр HeroService, когда он создает новый AppComponent.



Angular должен получить этот экземпляр откуда-то. Это функция Angular-ского Dependency Injector ("внедритель" зависимостей — далее Инъектор). Инъектор имеет контейнер предварительно созданных сервисов. Либо он находит и возвращает предварительно существующий экземпляр HeroService из контейнера, либо создает новый экземпляр, добавляет его в контейнер, и возвращает его в Angular.



Подробнее о внедрении зависимостей в главе Внедрение зависимостей.


Инъектор еще не знает, как создать HeroService. Если мы запустим наш код сейчас, Angular выдаст ошибку:



    EXCEPTION: No provider for HeroService! (AppComponent -> HeroService)


Мы должны научить инъектор, как ему создать HeroService путем регистрации поставщика (provider) HeroService. Чтобы это сделать, нужно добавить свойство массива providers в нижней части метаданных компонента в вызове @Component.



app.component.ts (providing HeroService)



    providers: [HeroService]


Массив providers указывает Angular, что нужно создать новый экземпляр HeroService, когда он создает новый AppComponent. AppComponent может использовать этот сервис, чтобы получить героев, и кроме того, его может получить каждый потомок компонента в дереве этого компонентов.



Сервисы и дерево компонентов


Напомним, что AppComponent создает экземпляр HeroDetail, на основании тэга в нижней части его шаблона. Компонент HeroDetail является потомком AppComponent.



Если компоненту HeroDetailComponent требуется HeroService родительского компонента, он попросит Angular внедрить сервис в его конструктор, который будет выглядеть так же, как для AppComponent:



hero-detail.component.ts (конструктор)



constructor(private heroService: HeroService) { }


Компонент HeroDetailComponent не должен повторять массив providers своего родителя! Подумайте, почему. В приложении ниже это будет рассмотрено более подробно.



AppComponent является компонентом самого высокого уровня нашего приложения. В приложении должен быть только один экземпляр этого компонента и только один экземпляр HeroService во всем нашем приложении.



getHeroes в AppComponent


У нас есть сервис в приватной переменной heroService. Давайте используем ее.



Сделаем паузу, чтобы подумать. Мы можем вызвать сервис и получить данные в одной строке.



    this.heroes = this.heroService.getHeroes();


В самом деле, нам не нужен специальный метод, чтобы обернуть одну строку. Мы пишем это в любом случае:



app.component.ts (getHeroes)



      getHeroes() {
this.heroes = this.heroService.getHeroes();
}


Хук ngOnInit жизненного цикла


AppComponent должен получать и отображать героев без лишней суеты. Где нам лучше вызвать getHeroes? В конструкторе? Не надо так делать!



Многолетний опыт и горькие слезы научили нас выносить сложную логику из конструктора, особенно ту, что может использовать сервер как источник данных.



Конструктор предназначен для простых инициализаций, вроде присвоения параметров конструктора к свойствам. Но не для тяжелых вещей. Мы должны иметь возможность создать компонент в тесте и не беспокоиться, что он может делать реальную работу — такую, как вызов сервера! — пока мы не скажем ему это сделать.



Если нет конструктора, то кто-то должен сделать вызов метода getHeroes.



Angular сделает это, если мы реализуем ngOnInit Lifecycle Hook (хук жизненного цикла ngOnInit). Angular предлагает ряд интерфейсов для того, чтобы участвовать в критических моментах жизненного цикла компонента: при создании, после каждого изменения, и при его окончательном уничтожении.



Каждый интерфейс имеет один метод. Когда компонент реализует этот метод, Angular делает его вызов в соответствующее время.



Подробнее о жизненном циклом хуков в главе Жизненный цикл хуков.


Вот краткое описание интерфейса OnInit:



app.component.ts (протокол OnInit)



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

export class AppComponent implements OnInit {
ngOnInit() {
}
}


Мы пишем метод ngOnInit с нашей логикой инициализации внутри и предоставляем Angular-у вызвать его в нужное время. В нашем случае, инициализация заключается в вызове getHeroes.



app.component.ts (протокол OnInit)



      ngOnInit() {
this.getHeroes();
}


Наше приложение, как и ожидалось, показывает список героев и вид с детальной информацией о герое, когда мы нажимаем на имя героя.



Мы становимся ближе. Но кое-что еще не совсем правильно.



Асинхронные сервисы и обещания (promises)



Наш HeroService возвращает список фиктивных героев сразу. Это сигнатура синхронного вызова getHeroes:



    this.heroes = this.heroService.getHeroes();


Стоит запросить героев, и они есть в возвращаемом результате.



В будущем мы собираемся получить героев с удаленного сервера. Пока что мы не будем использовать HTTP, но будем стремиться к этому в следующих главах.



Когда мы делаем вызов, нам нужно дождаться ответа сервера, и мы не сможем блокировать пользовательский интерфейс, пока мы ждем, даже если мы захотим (хотя и не должны), так как браузер не заблокируешь.



Нам придется использовать какой-то асинхронный метод получения данных, который изменит сигнаруту нашего метода getHeroes.



Мы будем использовать обещания.



Сервис героев дает обещание


Обещание… ну, это обещание сделать наш вызов позже, когда результаты будут готовы. Мы просим асинхронный сервис, чтобы он выполнил какую-то работу, и отдал функцию обратного вызова. Он делает эту работу (где-то) и в конце концов он вызывает нашу функцию с результатами работы или с ошибкой.



Это упрощенное описание. Узнать о ES2015 обещаниях можно здесь и в других местах в Интернете.


Обновим HeroService, используя метод, возвращающий обещание getHeroes:



hero.service.ts (getHeroes)



    getHeroes() {
return Promise.resolve(HEROES);
}


Мы все еще используем фиктивные данные. Мы имитируем поведение сверхскоростного, с нулевой задержкой сервера, возвращая уже разрешенное (выполненное) обещание с фиктивным списком наших героев, как результат.



Выполнение обещания


Возвращаясь к компоненту AppComponent и методу getHeroes, мы видим, что он по-прежнему выглядит следующим образом:



app.component.ts (getHeroes — старый вариант)



    getHeroes() {
this.heroes = this.heroService.getHeroes();
}


В результате нашего изменения в HeroService, мы переделаем this.heroes на работу с обещанием, вместо массива героев.



Мы должны изменить нашу реализацию, чтобы выполнить обещание, когда оно разрешено (выполнено). Когда обещание разрешено успешно, тогда у нас будут герои для отображения.



Мы передаем нашу функцию обратного вызова как аргумент методу обещания then:



app.component.ts (getHeroes — новый вариант)



    getHeroes() {
this.heroService.getHeroes().then(heroes => this.heroes = heroes);
}


Функция стрелки ES2015 в обратном вызове является более емкой, чем использование эквивалентной функции, и изящно работает с this.


Наш обратный вызов присваивает свойству компонента heroes массив героев, который вернул сервис. Вот и все!



Наше приложение должно по-прежнему показывать список героев, и отображать детальное представление о герое при выборе его из списка.



Перейдите в приложение "Получи это медленно" чтобы увидеть, как будет выглядеть получение данных с плохим соединением (задержкой ответа).


Обзор структуры приложения



Давайте проверим, что мы имеем следующую структуру после нашего замечательного рефакторинга в этой главе:



    angular2-tour-of-heroes
app
app.component.ts
hero.ts
hero-detail.component.ts
hero.service.ts
main.ts
mock-heroes.ts
node_modules ...
typings ...
index.html
package.json
tsconfig.json
typings.json


Файлы кода, которые мы обсуждали в этой главе.



app/hero.service.ts
    import { Injectable } from '@angular/core';
import { Hero } from './hero';
import { HEROES } from './mock-heroes';
@Injectable()
export class HeroService {
getHeroes() {
return Promise.resolve(HEROES);
}
// See the "Take it slow" appendix
getHeroesSlowly() {
return new Promise(resolve =>
setTimeout(()=>resolve(HEROES), 2000) // 2 seconds
);
}
}


app/app.component.ts
    import { Component, OnInit } from '@angular/core';
import { Hero } from './hero';
import { HeroDetailComponent } from './hero-detail.component';
import { HeroService } from './hero.service';
@Component({
selector: 'my-app',
template:`

{{title}}


My Heroes




  • {{hero.id}} {{hero.name}}



`,
styles:[`
.selected {
background-color: #CFD8DC !important;
color: white;
}
.heroes {
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 15em;
}
.heroes li {
cursor: pointer;
position: relative;
left: 0;
background-color: #EEE;
margin: .5em;
padding: .3em 0;
height: 1.6em;
border-radius: 4px;
}
.heroes li.selected:hover {
background-color: #BBD8DC !important;
color: white;
}
.heroes li:hover {
color: #607D8B;
background-color: #DDD;
left: .1em;
}
.heroes .text {
position: relative;
top: -3px;
}
.heroes .badge {
display: inline-block;
font-size: small;
color: white;
padding: 0.8em 0.7em 0 0.7em;
background-color: #607D8B;
line-height: 1em;
position: relative;
left: -1px;
top: -4px;
height: 1.8em;
margin-right: .8em;
border-radius: 4px 0 0 4px;
}
`],
directives: [HeroDetailComponent],
providers: [HeroService]
})
export class AppComponent implements OnInit {
title = 'Tour of Heroes';
heroes: Hero[];
selectedHero: Hero;
constructor(private heroService: HeroService) { }
getHeroes() {
this.heroService.getHeroes().then(heroes => this.heroes = heroes);
}
ngOnInit() {
this.getHeroes();
}
onSelect(hero: Hero) { this.selectedHero = hero; }
}


app/mock-heroes.ts
    import { Hero } from './hero';
export var HEROES: Hero[] = [
{"id": 11, "name": "Mr. Nice"},
{"id": 12, "name": "Narco"},
{"id": 13, "name": "Bombasto"},
{"id": 14, "name": "Celeritas"},
{"id": 15, "name": "Magneta"},
{"id": 16, "name": "RubberMan"},
{"id": 17, "name": "Dynama"},
{"id": 18, "name": "Dr IQ"},
{"id": 19, "name": "Magma"},
{"id": 20, "name": "Tornado"}
];


Путь, который мы прошли



Давайте подведем итоги того, что мы создали.




  • Мы создали сервисный класс, к которому могут получить доступ несколько компонентов.

  • Мы использовали хук ngOnInit жизненного цикла, чтобы получить наших героев при активации AppComponent.

  • Мы определили наш HeroService в качестве поставщика для AppComponent.

  • Мы создали фиктивные данные героев и импортировали их в наш сервис.

  • Мы произвели разработку нашего сервиса так, чтобы он вернул обещание, и наш компонент, чтобы он получил наши данные из обещания.



Запустить приложение, часть 4



Предстоящий путь



Наш Тур героев стал более пригоден для повторного использования с применением общих компонентов и сервисов. Мы хотим создать информационную панель, добавить ссылки меню, для маршрутизации между представлениями, а также форматировать данные в шаблоне. По мере развития нашего приложения, мы узнаем, как его спроектировать, чтобы упростить его расширение и поддержку.



Мы узнаем о компоненте маршрутизации Angular и навигации между представлениями в следующей главе.



Приложение: Получи это медленно



Мы можем эмулировать медленное соединение.



Импортируйте тип Hero и добавьте следующий метод getHeroesSlowly в HeroService



hero.service.ts (getHeroesSlowy)



    getHeroesSlowly() {
return new Promise(resolve =>
setTimeout(()=>resolve(HEROES), 2000) // 2 seconds
);
}


Также, как и getHeroes, этот метод возвращает обещание. Но это обещание делает задержку в 2 секунды до разрешения с фиктивным списком героев.



Вернувшись в AppComponent, замените heroService.getHeroes на heroService.getHeroesSlowly и посмотрите, как будет вести себя приложение.



Приложение: Теневое клонирование (shadowing) родительского сервиса



Мы говорили ранее, что если мы включаем родительский AppComponent HeroService в HeroDetailComponent, мы не должны добавлять массив провайдеров в метаданные HeroDetailComponent.



Почему? Потому что этим мы скажем Angular, что нужно создать новый экземпляр HeroService на уровне HeroDetailComponent. Компоненту HeroDetailComponent не нужен свой собственный экземпляр сервиса; ему нужен экземпляр сервиса его родителя. Добавление массива providers создает новый экземпляр сервиса, который является клоном родительского экземпляра.



Подумайте хорошенько о том, где и когда нужно регистрировать поставщика. Понять область видимости этой регистрации. Будьте осторожны, чтобы не создать новый экземпляр сервиса на неправильном уровне.



Важное замечание. С выходом очередного релиза в Angular произошли изменения в директиве ngFor.

Вместо, например, *ngFor="#hero of heroes" нужно использовать новый синтаксис *ngFor="let hero of heroes".


Пока что при использовании старого синтаксиса появляется только предупреждение.



Original source: habrahabr.ru.

https://habrahabr.ru/post/283556/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
Мария_Апанович

Жалюзи из газет. Мастер-класс | Домохозяйка

Пятница, 13 Мая 2016 г. 21:05 (ссылка)
domohozyajka.com/2015/06/zh...ter-klass/

Комментарии (0)КомментироватьВ цитатник или сообщество
ЮЛИ-АННА

Валяние из шерсти. Зимние птички.

Среда, 11 Мая 2016 г. 11:27 (ссылка)

Это цитата сообщения Марриэтта Оригинальное сообщение

Валяние из шерсти. Зимние птички




Читать далее...
Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
Лиса26

Пасхальные цыплята из помпонов. Мастер-класс | Домохозяйка

Понедельник, 09 Мая 2016 г. 13:19 (ссылка)
domohozyajka.com/2015/03/pa...r-klass-2/


Комментарии (0)КомментироватьВ цитатник или сообщество
Лиса26

Воробей Прошка из ниток. Мастер – класс | Домохозяйка

Понедельник, 09 Мая 2016 г. 13:13 (ссылка)
domohozyajka.com/2015/02/vo...ter-klass/


Воробей Прошка из ниток и его друзья. Мастер – класс

Комментарии (0)КомментироватьВ цитатник или сообщество
Синтез

Мотив Звездочка на вилке - gaanna.ru

Воскресенье, 08 Мая 2016 г. 20:31 (ссылка)
gaanna.ru/page/motiv-zvezdochka-na-vilke


Мотив Звездочка на вилке



 

Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

[Перевод] Angular 2 Beta, обучающий курс «Тур героев» часть 3

Среда, 27 Апреля 2016 г. 19:55 (ссылка)

Наше приложение растет. В этой части сосредоточимся на компонентах, пригодных для повторного использования, а также на передаче данных компонентам. Давайте отделим список героев в отдельный компонент и сделаем этот компонент пригодным для повторного использования.



Запустить приложение, часть 3



Где мы остановились



Прежде чем продолжить наш Тур героев, давайте проверим, что наш проект имеет следующую структуру. Если это не так, нужно будет вернуться к предыдущим главам.



    angular2-tour-of-heroes
app
app.component.ts
main.ts
node_modules ...
typings ...
index.html
package.json
tsconfig.json
typings.json


Поддержка преобразования кода и выполнения приложения



Нам нужно запустить компилятор TypeScript, чтобы при этом он отслеживал изменения в файлах и сразу выполнял компиляцию, а также запустить наш web-сервер. Мы сделаем это, набрав



    npm start


Это позволит держать приложение запущенным, пока мы продолжаем создавать Тур героев.



Создание компонента детальной информации о герое



Список героев и детальная информация о герое находятся в одном и том же компоненте, в одном файле. Пока что они невелики, но каждый из них может вырасти. Мы можем получить новые требования к одному из них, что потребует изменения только одного, но не другого. Тем не менее, каждое изменение таит опасность ошибок для двух компонентов и удваивает тестирование. Если бы возникла необходимость повторно использовать детальную информацию о герое в другом месте нашего приложения, нам пришлось бы прихватить и список героев.



Наш текущий компонент нарушает единый принцип ответственности. Этот материал всего лишь урок, но мы можем сделать все правильно — тем более, что это не так сложно. Кроме того, в процессе мы узнаем больше о том, как строить приложения в Angular.



Давайте извлечем детальную информацию о герое в свой собственный компонент.



Отделяем детальную информацию о герое



Добавим новый файл с именем hero-detail.component.ts в папку app и создадим HeroDetailComponent, как показано ниже.



hero-detail.component.ts (первоначальная версия)



    import {Component, Input} from 'angular2/core';

@Component({
selector: 'my-hero-detail',
})
export class HeroDetailComponent {
}


Cоглашения об именовании


Мы хотели бы понять с первого взгляда, какие классы являются компонентами (по названию класса) и какие файлы содержат компоненты (по названию файла).



Обратите внимание на то, что у нас есть AppComponent в файле с именем app.component.ts и наш новый HeroDetailComponent находится в файле с именем hero-detail.component.ts.



Все наши составные имена классов заканчиваются на "Component". Все наши составные имена файлов заканчиваются на ".component".



Мы переводим имена файлов в "нижний регистр с тире" (kebab-case), поэтому мы не беспокоимся о чувствительности к регистру на сервере или в системе управления версиями.



Рассмотрим вышеприведенный код.



Мы начали с импорта декораторов Angular — Component и Input, потому что они скоро нам понадобятся.

Затем мы создаем метаданные с декоратором @Component, где мы указываем имя селектора, который идентифицирует элемент компонента. Затем мы экспортируем класс, чтобы сделать его доступным для других компонентов.



Закончив здесь, мы импортируем его в AppComponent и создадим соответствующий элемент

.



Шаблон детальной информации о герое



В данный момент, представления Heroes и Hero Detail объединены в один шаблон в AppComponent. Давайте вырежем содержимое Hero Detail из AppComponent и вставим его в новое свойство шаблона HeroDetailComponent.



Ранее мы привязывали свойство selectedHero.name в AppComponent. Наш HeroDetailComponent будет иметь свойство hero, а не свойство selectedHero. Таким образом, мы заменим selectedHero на hero повсюду в нашем новом шаблоне. Это наше единственное изменение. Результат будет выглядеть так:



hero-detail.component.ts (шаблон)



    template: `

{{hero.name}} details!


{{hero.id}}






`


Теперь наша разметка детальной информации о герое существует только в HeroDetailComponent.



Добавление свойства hero



Добавим свойство hero, о котором мы говорили выше, к классу компонента.



    hero: Hero;


Ой-ой. Мы объявили свойство hero как тип Hero, но наш класс героя находится в файле app.component.ts. У нас есть два компонента, каждый из которых в своем собственном файле, которые должны ссылаться на класс Hero.



Мы решим эту проблему, переместив класс Hero из app.component.ts в свой собственный файл hero.ts.



hero.ts (Экспортированный класс Hero)



    export class Hero {
id: number;
name: string;
}


Мы экспортируем класс Hero из hero.ts, потому что нам нужно ссылаться на него в обоих файлах компонентов. Добавьте следующий оператор импорта в верхней части app.component.ts и hero-detail.component.ts.



hero-detail.component.ts и app.component.ts (Импорт класса Hero)



    import {Hero} from './hero';


Свойство hero является входящим.



Нужно сказать компоненту HeroDetailComponent, какого героя ему отобразить. Кто ему скажет это? Родитель AppComponent!



AppComponent знает, какого героя показать: героя, который пользователь выбрал из списка. Выбор пользователя находится в свойстве selectedHero.



Мы обновим шаблон AppComponent так, что он свяжет свое свойство selectedHero со свойством hero нашего HeroDetailComponent. Связывание может выглядеть следующим образом:



    


Обратите внимание на то, что свойство hero является целевым свойством — оно в квадратных скобках слева от (=).



Angular требует, чтобы объявленное целевое свойство было входящим свойством. Если мы это не сделаем, Angular откажет в связывании и выдаст сообщение об ошибке.



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


Есть несколько способов, как указать, что hero является входящим. Мы сделаем это предпочтительным способом, аннотировав свойство hero декоратором @Input, которое мы импортировали ранее.



    @Input() 
hero: Hero;


Узнать больше о декораторе @Input() можно в главе Директивы атрибутов.


Обновление AppComponent



Вернемся к AppComponent и научим его использовать HeroDetailComponent.



Начнем с импорта HeroDetailComponent, чтобы можно было сослаться на него.



    import {HeroDetailComponent} from './hero-detail.component';


Найдем место в шаблоне, где мы удалили содержимое Hero Detail и добавим тег элемента, который представляет HeroDetailComponent.



    


my-hero-detail — имя, которое мы установили в свойстве selector метаданных HeroDetailComponent.


Эти два компонента не будет скоординированы, пока мы не свяжем свойство selectedHero компонента AppComponent со свойством hero компонента HeroDetailComponent, например так:



    


Шаблон AppComponent должен выглядеть следующим образом:

app.component.ts (Шаблон)



    template:`

{{title}}


My Heroes




  • {{hero.id}} {{hero.name}}



`,


Благодаря связыванию, HeroDetailComponent должен получить героя от AppComponent и отобразить детальную информацию этого героя под списком. Эта информация должна обновляться каждый раз, когда пользователь выбирает нового героя.



Это пока что не происходит!



Щелкаем в списке героев. Никакой информации. Мы ищем ошибки в консоли "Инструменты разработчика браузера". Ошибок нет.



Выглядит так, будто Angular игнорирует новый тег. Все это потому, что он действительно игнорирует новый тег.



Массив директив



Браузер игнорирует неизвестные ему HTML теги и атрибуты. Так же поступает и Angular.



Мы импортировали HeroDetailComponent и использовали его в шаблоне, но мы не сказали Angular об этом.



Мы говорим об этом Angular путем перечисления этого компонента в метаданных, в массиве directives. Добавим этот массив свойств в нижней части конфигурации @Component, сразу после template и styles.



    directives: [HeroDetailComponent]


Заработало!



Когда мы просматриваем наше приложение в браузере, мы видим список героев. Когда мы выбираем героя, мы видим детальную информацию о нем.



Принципиальное изменение в том, что мы можем использовать этот компонент HeroDetailComponent, чтобы отобразить детальную информацию о герое где-нибудь в другом месте приложения.



Мы создали наш первый повторно используемый компонент!



Обзор структуры приложения



Давайте проверим, что после проведенного в этой главе рефакторинга, у нас следующая структура проекта:



    angular2-tour-of-heroes
app
app.component.ts
hero.ts
hero-detail.component.ts
main.ts
node_modules ...
typings ...
index.html
package.json
tsconfig.json
typings.json


Файлы кода, которые мы обсуждали в этой главе.



app/hero-detail.component.ts
    import {Component, Input} from 'angular2/core';
import {Hero} from './hero';

@Component({
selector: 'my-hero-detail',
template: `

{{hero.name}} details!


{{hero.id}}






`
})
export class HeroDetailComponent {
@Input()
hero: Hero;
}


app/app.component.ts
    import {Component} from 'angular2/core';
import {Hero} from './hero';
import {HeroDetailComponent} from './hero-detail.component';

@Component({
selector: 'my-app',
template:`

{{title}}


My Heroes




  • {{hero.id}} {{hero.name}}



`,
styles:[`
.selected {
background-color: #CFD8DC !important;
color: white;
}
.heroes {
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 15em;
}
.heroes li {
cursor: pointer;
position: relative;
left: 0;
background-color: #EEE;
margin: .5em;
padding: .3em 0;
height: 1.6em;
border-radius: 4px;
}
.heroes li.selected:hover {
background-color: #BBD8DC !important;
color: white;
}
.heroes li:hover {
color: #607D8B;
background-color: #DDD;
left: .1em;
}
.heroes .text {
position: relative;
top: -3px;
}
.heroes .badge {
display: inline-block;
font-size: small;
color: white;
padding: 0.8em 0.7em 0 0.7em;
background-color: #607D8B;
line-height: 1em;
position: relative;
left: -1px;
top: -4px;
height: 1.8em;
margin-right: .8em;
border-radius: 4px 0 0 4px;
}
`],
directives: [HeroDetailComponent]
})
export class AppComponent {
title = 'Tour of Heroes';
heroes = HEROES;
selectedHero: Hero;
onSelect(hero: Hero) { this.selectedHero = hero; }
}

var HEROES: Hero[] = [
{ "id": 11, "name": "Mr. Nice" },
{ "id": 12, "name": "Narco" },
{ "id": 13, "name": "Bombasto" },
{ "id": 14, "name": "Celeritas" },
{ "id": 15, "name": "Magneta" },
{ "id": 16, "name": "RubberMan" },
{ "id": 17, "name": "Dynama" },
{ "id": 18, "name": "Dr IQ" },
{ "id": 19, "name": "Magma" },
{ "id": 20, "name": "Tornado" }
];


app/hero.ts
    export class Hero {
id: number;
name: string;
}


Путь, который мы прошли



Давайте подведем итоги того, что мы создали.




  • Мы создали компонент, который можно использовать повторно.

  • Мы узнали, как сделать, чтобы компонент принимал входные данные.

  • Мы научились связывать родительский компонент с дочерним компонентом.

  • Мы научились объявлять нужные нам директивы приложения в массиве directives.



Запустить приложение, часть 3



Предстоящий путь



Наш тур героев стал более подходящим для многократного использования с разделяемыми компонентами.



Мы все еще получаем наши данные о героях (используя заглушку для их получения) в AppComponent. Это не лучший вариант. Мы должны сделать рефакторинг доступа к данным, вынеся получение данных в отдельный сервис, и расшарить этот сервис компонентам, которым необходимы эти данные.



Мы будем учиться создавать сервисы в следующей главе.



Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/282634/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
ZAREMA19

Paper Rose Tutorial

Суббота, 23 Апреля 2016 г. 20:20 (ссылка)





Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
СитковаЛюдмила

Мини подставочки под сладости. Мастер-класс | Домохозяйка

Пятница, 22 Апреля 2016 г. 22:50 (ссылка)
domohozyajka.com/2015/01/mi...ter-klass/

Подставочки для сладостей ко Дню Святого Валентина от Автора этой подставки для кексов и пирожных. Сделать самому эти оригинальные мини–этажерки очень легко и
Комментарии (1)КомментироватьВ цитатник или сообщество
СитковаЛюдмила

Тапочки-кеды крючком | Домохозяйка

Пятница, 22 Апреля 2016 г. 22:47 (ссылка)
domohozyajka.com/2015/01/ta...kryuchkom/

Такие тапочки вяжутся очень легко
Комментарии (0)КомментироватьВ цитатник или сообщество
СитковаЛюдмила

Цветочное одеяло крючком. Видео | Домохозяйка

Пятница, 22 Апреля 2016 г. 22:39 (ссылка)
domohozyajka.com/2015/03/cv...kom-video/

Такой роскошный плед для своего малыша мы можем легко, быстро и просто связать крючком по представленным видео-мастер-классам.
Комментарии (0)КомментироватьВ цитатник или сообщество
СитковаЛюдмила

Нежный браслет из бусин. Мастер-класс | Домохозяйка

Пятница, 22 Апреля 2016 г. 21:49 (ссылка)
domohozyajka.com/2015/06/ne...ter-klass/

Веселенький и нежный летний браслет авторства магазина мастера «Pandahallbeads». Фото и текст Автора.
Комментарии (0)КомментироватьВ цитатник или сообщество
СитковаЛюдмила

Пасхальная курочка из бумажной лозы. Мастер-класс | Домохозяйка

Пятница, 22 Апреля 2016 г. 21:47 (ссылка)
domohozyajka.com/2016/04/pa...ter-klass/

Роскошная плетеная корзинка-курочка для пасхальных яиц.
Комментарии (0)КомментироватьВ цитатник или сообщество
Таньчик_Александровна

Ступенчатое прибавление на филейном вязании в конце ряда - gaanna.ru

Четверг, 21 Апреля 2016 г. 19:49 (ссылка)
gaanna.ru/page/stupenchatoe...once-rjada

Урок по прибавлению заполненных клеточек в конце ряда филейной сетки есть на моем канале уже давно. По просьбе одной из своих подписчиц я сняла видео по прибавлению в конце ряда пустых клеточек.
Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
ellej-crochet

Цветочная кайма Хоровод | Crochet by Ellej

Четверг, 21 Апреля 2016 г. 14:40 (ссылка)
ellej.org/obvyazka-kraya/cv...?_utl_t=li


Цветочная кайма Хоровод | Crochet by Ellej | Crochet by Ellej | Вязание крючком от Елены Кожухарь



 



 





Комментарии (0)КомментироватьВ цитатник или сообщество
Таньчик_Александровна

Ступенчатое прибавление на филейном вязании в конце ряда - gaanna.ru

Среда, 21 Апреля 2016 г. 00:43 (ссылка)
gaanna.ru/page/stupenchatoe...once-rjada

Урок по прибавлению заполненных клеточек в конце ряда филейной сетки есть на моем канале уже давно. По просьбе одной из своих подписчиц я сняла видео по прибавлению в конце ряда пустых клеточек.
Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество

Следующие 30  »

<tutorial - Самое интересное в блогах

Страницы: [1] 2 3 ..
.. 10

LiveInternet.Ru Ссылки: на главную|почта|знакомства|одноклассники|фото|открытки|тесты|чат
О проекте: помощь|контакты|разместить рекламу|версия для pda