(recieveChanges)="recieveChanges($event)"
||
@Output() changeEvent = new EventEmitter<string>();
(changeEvent)="recieveChanges($event)"
carousel {
display: block;
}
:host
если стили внутри компонента <table *ngIf="view" #table>
@ViewChild('table')
set tableEl(el: ElementRefl) {
if(el) {
el.nativeElement.scrollIntoView();
}
}
/**
* Provides a stream containing the latest data array to render. Influenced by the table's
* stream of view window (what rows are currently on screen).
*/
@Input()
get dataSource(): DataSource<T> { return this._dataSource; }
import { DataSource } from '@angular/cdk'
import { Observable } from 'rxjs/Observable'
import 'rxjs/add/observable/of'
export class MyDataSource extends DataSource<any> {
connect(): Observable<any[]> {
return Observable.of([
{id: 1, title: 'Test 1'},
{id: 2, title: 'Test 2'},
{id: 3, title: 'Test 3'},
]);
}
disconnect() {}
}
public dataSource: DataSource = new MyDataSource();
@Directive({
selector: '[outsideClickHandler]',
})
export class OutsideClickDirective {
@Output('outsideClickHandler') close = new EventEmitter();
isOpen: boolean = false;
constructor(private elRef: ElementRef) {}
@HostListener('document:click', ['$event'])
public handleClick(event) {
if (!this.isOpen) {
this.isOpen = true;
} else if (!this.elRef.nativeElement.contains(event.target)) {
this.close.emit();
}
}
}
<div class="editable-edit-box" (outsideClickHandler)="onClose()">
<z *ngIf="zOf(x, y) as z" (disabled)="disabled(z)" (selected)="selected(z)"></z>
<z *ngIf="{ of: zOf(x, y) } as z" (disabled)="disabled(z.of)" (selected)="selected(z.of)"></z>
@Output
код будет исполняться при срабатывании соответствующего подписчика. Так что я не понимаю зачем вам тут переменная console.log("usersService body: "+body);
return body.data || { };
data
, соответственно ваш сервис возвращает пустой объект.console.log("appComponent.users: "+this.users);
this.usersService.getUsers()
.subscribe(
users => {
console.log(users);
this.users = users;
},
error => this.errorMessage = <any>error);
private extractData(res: Response) {
return res.json() || [];
}
npm install karma-jasmine-html-reporter --save-dev
client: {
clearContext: false
}
BehaviorSubject
объекта есть метод getValue
this.cartService.cart.next(this.cartService.cart.getValue().push(prod));
@Directive({
selector: '[hasRole]'
})
export class HasRoleDirective implements OnInit {
@Input() hasRole: Array<string>;
constructor(private viewContainerRef: ViewContainerRef,
private template: TemplateRef<any>) {}
ngOnInit() {
this.checkRoles('user');
}
checkRoles(userRole: string) {
console.log("Роль пользователя: " + userRole);
if (!this.hasRole || this.hasRole.indexOf(userRole) != -1) {
console.log("Есть доступ");
this.viewContainerRef.createEmbeddedView(this.template);
} else {
this.viewContainerRef.clear();
console.log("Доступ запрещен");
}
}
}
<p *hasRole="['admin', 'user']"><Блок идят только Админ и Пользователь</p>
<div *hasRole="['admin']">Тестовый блок который видит только Админ</div>
<template [hasRole]="['admin', 'user']">
<p>Тестовый параграф которые видят только Админ и Пользователь</p>
</template>
<template [hasRole]="['admin']">
<div>Тестовый блок который видит только Админ</div>
</template>
Observable
и используем AsyncPipe
, который сделает всю грязную работу за нас*ngFor="let release of releases | async"
releases: Observable<any[]>;
constructor(private releasesService: ReleasesService) {}
ngOnInit() {
this.releases = this.releasesService.getReleases();
}
releases: any[];
constructor(private releasesService: ReleasesService) {}
ngOnInit() {
this.releasesService.getReleases()
.subscribe(data => this.releases = data);
}
import { UpperCasePipe, LowerCasePipe } from '@angular/common'
const PIPES_COLLECTION = {
'uppercase': new UpperCasePipe(),
'lowercase': new LowerCasePipe()
};
@Pipe({
name: 'dynamicPipe'
})
export class DynamicPipe implements PipeTransform {
transform(val, pipeName: string) {
return PIPES_COLLECTION[pipeName].transform(val);
}
}
@Directive({
selector: '[dynamicPipe]'
})
export class DynamicPipeDirective {
@Input() dynamicPipe: DynamicPipeModel;
cmpRef: ComponentRef<any>;
constructor(private vcRef: ViewContainerRef, private compiler: Compiler) {}
ngAfterViewInit() {
const data = this.dynamicPipe.name;
const pipe = this.dynamicPipe.pipe;
@Component({
selector: 'dynamic-comp',
template: '{{ data | ' + pipe + '}}'
})
class DynamicComponent {};
@NgModule({
imports: [CommonModule],
declarations: [DynamicComponent]
})
class DynamicModule {}
this.compiler.compileModuleAndAllComponentsAsync(DynamicModule)
.then((moduleWithComponentsFactory) => {
const compFactory = moduleWithComponentsFactory.componentFactories.find(x => x.componentType === DynamicComponent);
const injector = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector);
this.cmpRef = this.vcRef.createComponent(compFactory, 0, injector, []);
this.cmpRef.instance.data = data;
});
}
ngOnDestroy() {
if(this.cmpRef) {
this.cmpRef.destroy();
}
}
}
@Component({
selector: 'saUiDatepicker',
template: `<input type="text" #input class="form-control datepicker" placeholder="{{placeholder}}" [(ngModel)]="value" (blur)="onBlur()">`,
providers: [CUSTOM_UI_DATEPICKER_CONTROL_VALUE_ACCESSOR]
})
export class UiDatepickerComponent implements OnInit, ControlValueAccessor {
private innerValue: any = '';
private onTouchedCallback: () => void = () => { };
private onChangeCallback: (_: any) => void = () => { };
get value(): any {
return this.innerValue;
};
set value(newValue: any) {
if (newValue === this.innerValue) return;
this.innerValue = newValue;
this.onChangeCallback(newValue);
}
@Input() options: any;
@Input() placeholder: any;
@ViewChild('input') el: ElementRef;
onBlur() {
this.onTouchedCallback();
}
writeValue(value: any) {
if (value !== this.innerValue) {
this.innerValue = value;
}
}
registerOnChange(fn: any) {
this.onChangeCallback = fn;
}
registerOnTouched(fn: any) {
this.onTouchedCallback = fn;
}
ngOnInit() {
let options = $.extend(this.options || {}, {
onSelect: (selectedDate) => {
this.onChangeCallback(selectedDate);
}
});
System.import('jquery-ui').then(() => {
const datePicker = $(this.el.nativeElement).datepicker(options);
if (this.value) {
datePicker.datepicker("setDate", this.value);
}
});
}
}
<form #templateForm="ngForm" (ngSubmit)="submit(templateForm.value)">
<saUiDatepicker name="data" [(ngModel)]="data" [options]="{...}"
placeholder="Выберите дату"></saUiDatepicker>
<button type="submit">Submit</button>
</form>
<form [formGroup]="reactiveForm">
<saUiDatepicker formControlName="data" [options]="{...}"
placeholder="Выберите дату"></saUiDatepicker>
<pre>{{ reactiveForm.value | json }}</pre>
</form>
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.reactiveForm = this.fb.group({
data: ''
});
}
new Intl.NumberFormat([locales[, options]])
import { CurrencyPipe } from '@angular/common';
const map = {
'RUB': 'ru-RU',
'JPY': 'ja-JP'
}
@Pipe({name: 'localizedCurrency'})
export class LocalizedCurrencyPipe implements PipeTransform {
transform(value: any, currencyCode: string = 'USD',
symbolDisplay: boolean = false, digits: string = null): string {
return new CurrencyPipe(map[currencyCode]).transform(value, currencyCode, symbolDisplay, digits);
}
}
<ng-container *ngFor="let row of review.penalty">
<tr *ngIf="row.sum > 10">
<td>{{row.name}}</td>
<td>{{row.sum | number:'.2'}}</td>
</tr>
</ng-container>
<template ngFor let-row [ngForOf]="review.penalty">
<tr *ngIf="row.sum > 10">
<td>{{row.name}}</td>
<td>{{row.sum | number:'.2'}}</td>
</tr>
</template>