I would like to fill a form by Id with Angular FormBuilder. My problem is that I don't now how to do it and i've try many of the topics solutions, but nothing really helps. here is what i want : when i click on a button update, another page opens with some fields that match, and thoose fields have to be filled. The parent component is working and is sending an Id via a router navigate. But the component that should catch and made the view working isn't working at all. Here is the code of that component :
import { Component, OnInit, OnDestroy, Input } from '#angular/core';
import { Subject } from 'rxjs';
import { Site } from '#shared/models/site.model';
import { MessagesService } from '#core/messages/messages.service';
import { FormBuilder, FormGroup, FormArray } from '#angular/forms';
import { BmrGenerationService } from './bmr-generation.service';
import { SiteService } from '#shared/services/site.service';
import { takeUntil } from 'rxjs/operators';
import { MmrService } from '#components/mmr/mmr.service';
import { Mmr } from '#shared/models/mmr.model';
#Component({
selector: 'idea-bmr-generation',
templateUrl: './bmr-generation.component.html',
styleUrls: ['./bmr-generation.component.scss']
})
export class BmrGenerationComponent implements OnInit, OnDestroy {
private unsubscribe$ = new Subject();
settings: any;
siteSelected: Site;
constructor(
private fb: FormBuilder,
private messageService: MessagesService,
private bmrGenerationService: BmrGenerationService,
private siteService: SiteService,
) { }
form: FormGroup;
isFormModified = false;
items: FormArray;
ngOnInit() {
this.createForm();
this.listenerForm();
// Lors d'un changement de site
this.siteService.currentSite$.pipe(takeUntil(this.unsubscribe$)).subscribe(
(site) => {
if (site) {
this.siteSelected = site;
this.getSettingsSite(site.id);
}
});
}
ngOnDestroy() {
this.unsubscribe$.next();
this.unsubscribe$.complete();
}
getSettingsSite(idSite: number): void {
/*this.adminSiteService.getSettingsBySite(idSite).subscribe((settings) => {
this.settings = settings;
this.createForm();
this.listenerForm();
});
}*/
}
createForm() {
this.form = this.fb.group({
productCode: [{ value: null, disabled: false }],
userReference: [{ value: null, disabled: false }],
productDescription: [{ value: null, disabled: false }],
});
}
listenerForm() {
if (this.form) {
this.form.valueChanges.subscribe(() => {
this.isFormModified = true;
});
}
}
onSubmit() {
if (this.isFormModified) {
this.isFormModified = false;
this.messageService.showSuccess('GENERATION_VERIF');
}
}
onCancel() {
if (this.isFormModified) {
this.createForm();
this.listenerForm();
this.isFormModified = false;
}
}
}
For example, i do't know how to replace the "null" values with the matching values. And i don't know how to get the Id in this component.
Here is the template :
<idea-section-container>
<div title>
<fa-icon icon="cogs"></fa-icon>
{{'BMR.GENERATION.TITLE' | translate}}
</div>
<div body>
<div class="site-container">
<form *ngIf="form" [formGroup]="form" (ngSubmit)="onSubmit()" class="site-form">
<div class="site-form-line">
<div class="site-form-label">
<div>
<fa-icon icon="info-circle" tooltipPosition="bottom" tooltipStyleClass="site-tooltip"
pTooltip="Code du produit OF">
</fa-icon>
</div>
<span>
{{'BMR.GENERATION.PRODUCT-CODE' | translate}}
</span>
</div>
<mat-form-field class="site-form-field" appearance="outline">
<mat-label>{{'BMR.GENERATION.PRODUCT-CODE' | translate}}</mat-label>
<input matInput formControlName="productCode">
</mat-form-field>
</div>
<div class="site-form-line">
<div class="site-form-label">
<div>
<fa-icon icon="info-circle" tooltipPosition="bottom" tooltipStyleClass="site-tooltip"
pTooltip="référence du MMR">
</fa-icon>
</div>
<span>
{{'BMR.GENERATION.MMR_REF' | translate}}
</span>
</div>
<mat-form-field class="site-form-field" appearance="outline">
<mat-label>{{'BMR.GENERATION.MMR_REF' | translate}}</mat-label>
<input matInput formControlName="mmrReference">
</mat-form-field>
</div>
<div class="site-form-line">
<div class="site-form-label">
<div>
<fa-icon icon="info-circle" tooltipPosition="bottom" tooltipStyleClass="site-tooltip"
pTooltip="Description du produit">
</fa-icon>
</div>
<span>
{{'BMR.GENERATION.PRODUCT_DESCRIPTION' | translate}}
</span>
</div>
<mat-form-field class="site-form-field" appearance="outline">
<mat-label>{{'BMR.GENERATION.PRODUCT_DESCRIPTION' | translate}}</mat-label>
<input matInput formControlName="productDescription">
</mat-form-field>
</div>
<div class="margin-top20 site-form-footer">
<idea-button type="submit" color="principal-blue" [disabled]="!isFormModified" class="margin-right20">
{{'BMR.GENERATION.SAVE' | translate}}
</idea-button>
<idea-button type="button" color="principal-blue" [disabled]="!isFormModified" (click)="onCancel()">
{{'GENERAL.CANCEL' | translate}}
</idea-button>
</div>
</form>
</div>
</div>
</idea-section-container>
No error is displayed within the console.
Thank you for any help.
You can change the formControlName of the form elements in another page which open up on click of button and make it same as the id which is sent from previous page.
Then you can use
this.form.control.idSentFromPreviousPage.setValue(valueFromPreviousPage)
Related
My task: The received value from service 1 or 2, depending on the value, change the styles in the html component. Using the ng-switch directive, I expect to compare the value received from the object with the specified template value. Styles are not applied. The main problem is that the styles are not applied
My component:
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, Self } from '#angular/core';
import { ConfigService, IProductListItem, SliderValueOptions } from 'common-modules';
import { Router } from '#angular/router';
import { debounceTime, filter, takeUntil, tap } from 'rxjs/operators';
import { NgOnDestroy } from '../../core/services/destroy.service';
import { BehaviorSubject } from 'rxjs';
import { OnInit, OnDestroy } from '#angular/core';
#Component({
selector: 'app-product-item',
templateUrl: './product-item.component.html',
styleUrls: ['./product-item.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [NgOnDestroy],
})
export class ProductItemComponent implements OnInit, OnDestroy {
#Input() product: IProductListItem;
#Input() doubleClickEnabled: boolean;
// tslint:disable-next-line:no-output-on-prefix
#Output() onAddToCart = new EventEmitter<any>();
themeProperties: number;
visibility: boolean = false;
constructor(private _router: Router, private _config: ConfigService, #Self() private onDestroy$: NgOnDestroy) {}
ngOnInit() {
this._config.marketplaceConfig.pipe(takeUntil(this.onDestroy$)).subscribe((config) => {
this.themeProperties = config.structure?.theme;
});
}
}
My html:
<mat-card class="card">
<div [ngSwitch]="themeProperties">
<ng-template *ngswitchcase="2">
{{ themeProperties }}
<mat-card id="cardbackground">
<a class="card__link" (click)="redirectToProduct(product)" (dblclick)="doubleClicked(product)">
<div
style="display: none"
class="card__promo"
*ngIf="product.priceWithDiscount && product?.promoIndividual?.percentDiscount"
>
-{{ product?.promoIndividual?.percentDiscount }}%
</div>
<!-- <b2b-modern-image mat-card-image [src]="product.photos[0]"></b2b-modern-image> -->
<img class="mat-card-image" [src]="product.photos" alt="" />
<mat-card-content class="card__content" [class.has-padding-top]="product && product['discount']">
<div class="super-sale">супер скидка</div>
<div *ngIf="product && product['discount']" class="discount">-{{ product['discount'] }}%</div>
<div
*ngIf="product && product.promoIndividual && product?.promoIndividual?.percentDiscount"
class="discount"
>
-{{ product?.promoIndividual?.percentDiscount }}
%
</div>
<ng-template #defaultPrice>
<!-- <span class="price">{{product.price}} ₽</span>-->
</ng-template>
<div class="rating">
<ngx-stars color="#ffd700" [readonly]="true" [initialStars]="product.rating || 0"> </ngx-stars>
<span class="ml-3">{{ product.views || 0 }} отзывов</span>
</div>
<h3 class="name wrap-two-line" [matTooltip]="product?.feed" matTooltipPosition="above">
{{ product | localize: 'name' }}
</h3>
<div class="а">
<div
class="d-flex align-items-center"
*ngIf="product.priceWithDiscount && product.priceWithDiscount != product.price; else defaultPrice"
>
<span class="price old">{{ product.price }}₽</span>
</div>
<p class="price">{{ (product.priceWithDiscount || 0).toFixed(1) }}₽</p>
</div>
</mat-card-content>
</a>
<mat-card-footer class="card__footer">
<a routerLink="/confirm-order" [queryParams]="{ products: product.id }" mat-raised-button color="primary">
Купить сейчас
</a>
<button mat-button color="primary" (click)="addToCart(product)">
<mat-icon>add_shopping_cart</mat-icon>
</button>
</mat-card-footer>
</mat-card>
</ng-template>
</div>
</mat-card>
change component to:
themeProperties$: Observable<number>;
...
ngOnInit() {
this.themeProperties$ = this._config.marketplaceConfig.pipe(map((config) => config.structure?.theme))
}
change template to:
<div [ngSwitch]="themeProperties$ | async">
<ng-container *ngSwitchCase="2">
....
</ng-container>
issues:
casing wrong on ngSwitchCase directive
OnPush change detection not running correctly, async pipe resolves
ng-template doesn't render to DOM. it's a template for use elsewhere. use ng-container instead.
The spelling of the template switch statement is case sensitive, should be *ngSwitchCase.
Also the ng-template does not work in this case, you need to use ng-container
So please change your statements to this layout, and all should work:
<ng-container *ngSwitchCase="2">
also because you are using ChangeDetectionStrategy.OnPush you need to trigger the change detection manually for the ngSwitch.
Here is a working example.
constructor(private _router: Router, private _config: ConfigService, #Self() private onDestroy$: NgOnDestroy, private cdr: ChangeDetectorRef) {}
ngOnInit() {
this._config.marketplaceConfig.pipe(takeUntil(this.onDestroy$)).subscribe((config) => {
this.themeProperties = config.structure?.theme;
this.cdr.detectChanges(); // <=== here, after setting the value
});
}
iam using ng-bootstrap to generate a popup modal, for example the first demo here https://ng-bootstrap.github.io/#/components/modal/examples, the problem here is,
when iam importing the FormsModule and ReactiveFormsModule in src/app/modal-basic.module.ts so the code inide it become like this
import { NgModule } from '#angular/core';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import { BrowserModule } from '#angular/platform-browser';
import { NgbModule } from '#ng-bootstrap/ng-bootstrap';
import { NgbdModalBasic } from './modal-basic';
#NgModule({ imports: [BrowserModule, NgbModule, FormsModule,ReactiveFormsModule],
declarations: [NgbdModalBasic],
exports:[NgbdModalBasic], bootstrap: [NgbdModalBasic]
})
export class NgbdModalBasicModule {}
and declaring a FormGroup in src/app/modal-basic so the code inside it become
import {Component} from '#angular/core';
import {FormGroup} from '#angular/forms';
import {NgbModal, ModalDismissReasons} from '#ng-bootstrap/ng-bootstrap';
#Component({
selector: 'ngbd-modal-basic',
templateUrl: './modal-basic.html'
})
export class NgbdModalBasic {
closeResult = '';
exampleFormName:FormGroup;
constructor(private modalService: NgbModal) {}
open(content) {
this.modalService.open(content, {ariaLabelledBy: 'modal-basic-title'}).result.then((result) => {
this.closeResult = `Closed with: ${result}`;
}, (reason) => {
this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
});
}
private getDismissReason(reason: any): string {
if (reason === ModalDismissReasons.ESC) {
return 'by pressing ESC';
} else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
return 'by clicking on a backdrop';
} else {
return `with: ${reason}`;
}
}
}
and in src/app/modal-basic.html when iam adding [formGroup]="exampleFormName" in the form tag or add formContrtrolName="elementName" to a control element, so the code become like that
<ng-template #content let-modal>
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">Profile update</h4>
<button type="button" class="close" aria-label="Close" (click)="modal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form [formGroup]="exampleFormName">
<div class="form-group">
<label for="dateOfBirth">Date of birth</label>
<div class="input-group">
<input id="dateOfBirth" class="form-control" placeholder="yyyy-mm-dd" name="dp" ngbDatepicker #dp="ngbDatepicker" formControlName="dateOfBirth">
<div class="input-group-append">
<button class="btn btn-outline-secondary calendar" (click)="dp.toggle()" type="button"></button>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark" (click)="modal.close('Save click')">Save</button>
</div>
</ng-template>
<button class="btn btn-lg btn-outline-primary" (click)="open(content)">Launch demo modal</button>
<hr>
<pre>{{ closeResult }}</pre>
i end up with a modal that doesn't popup but it appear after the last element in the page even though it was popup before adding
[formGroup]="exampleFormName" and formControlName="dateOfBirth"
i want to know where is the problem so please try the code form ng-bootstrap it self without my modifications then copy code from her and past it in stackblitz to se the problem.
thanks in advance.
You need use the FormControl for those inputs:
https://stackblitz.com/edit/angular-naoht3?file=src%2Fapp%2Fmodal-basic.ts
import { Component } from "#angular/core";
import {FormGroup, FormControl} from "#angular/forms"
import { NgbModal, ModalDismissReasons } from "#ng-bootstrap/ng-bootstrap";
#Component({
selector: "ngbd-modal-basic",
templateUrl: "./modal-basic.html"
})
export class NgbdModalBasic {
closeResult = "";
exampleFormName = new FormGroup({
name: new FormControl(),
dateOfBirth: new FormControl()
});
constructor(private modalService: NgbModal) {}
open(content) {
this.modalService
.open(content, { ariaLabelledBy: "modal-basic-title" })
.result.then(
result => {
this.closeResult = `Closed with: ${result}`;
},
reason => {
this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
}
);
}
private getDismissReason(reason: any): string {
if (reason === ModalDismissReasons.ESC) {
return "by pressing ESC";
} else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
return "by clicking on a backdrop";
} else {
return `with: ${reason}`;
}
}
}
I am Using Angular 7. i run this cmd ng build --prod build for protection.
That time i am caching this Error( Property 'service' is private and only accessible within class 'LoginComponent'):
ERROR in src\app\login\login.component.html(5,33): : Property 'service' is private and only accessible within class 'LoginComponent'.
src\app\login\login.component.html(18,104): : Property 'service' is private and only accessible within class 'LoginComponent'.
It's my HTML Code:
<div id="login_section" class="d-flex justify-content-center align-items-center">
<div class="login_cnt col-8 row">
<div class="col-6 d-flex justify-content-center py-4">
<form class="col-8" [formGroup]="service.loginform">
<h2 class="text-center">User Login</h2>
<mat-form-field class="col-12">
<input matInput type="text" placeholder="Username" formControlName="username" >
<mat-error>Username is Required</mat-error>
</mat-form-field>
<mat-form-field class="col-12">
<input matInput [type]="hide ? 'password' : 'text'" formControlName="password" placeholder="Password">
<mat-icon matSuffix (click)="hide = !hide">{{hide ? 'visibility_off' : 'visibility'}}</mat-icon>
<mat-error>Password is Required</mat-error>
</mat-form-field>
Forgot Password
<button mat-raised-button color="primary" class="float-right" [routerLink]="['/home']" [disabled]="service.loginform.invalid">Login</button>
</form>
</div>
</div>
</div>
It's My TS File:
import { Component, OnInit } from '#angular/core';
import { LoginService } from '../shared/login.service';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
username : string;
password: string;
hide = true;
constructor(private service: LoginService) { }
ngOnInit() {
}
}
when running ng serve am not catching it .
There are 2 ways to resolve this.
1.
Change private service: LoginService to public service: LoginService
As you are using AOT during compilation, you can not access private properties of your component in your HTML template.
2.
If you want to keep your service private, you can provide a public method in the controller which returns the service properties. You can call this method from your HTML template. It would be something like this:
Template:
<div id="login_section" class="d-flex justify-content-center align-items-center">
<div class="login_cnt col-8 row">
<div class="col-6 d-flex justify-content-center py-4">
<form class="col-8" [formGroup]="getLoginForm()"> <!-- Change here-->
<h2 class="text-center">User Login</h2>
<mat-form-field class="col-12">
<input matInput type="text" placeholder="Username" formControlName="username" >
<mat-error>Username is Required</mat-error>
</mat-form-field>
<mat-form-field class="col-12">
<input matInput [type]="hide ? 'password' : 'text'" formControlName="password" placeholder="Password">
<mat-icon matSuffix (click)="hide = !hide">{{hide ? 'visibility_off' : 'visibility'}}</mat-icon>
<mat-error>Password is Required</mat-error>
</mat-form-field>
Forgot Password
<button mat-raised-button color="primary" class="float-right" [routerLink]="['/home']" [disabled]="getLoginForm().invalid">Login</button> <!-- Change here-->
</form>
</div>
</div>
</div>
Controller:
import { Component, OnInit } from '#angular/core';
import { LoginService } from '../shared/login.service';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
username : string;
password: string;
hide = true;
constructor(private service: LoginService) { }
ngOnInit() {
}
getLoginForm() {
return this.service.loginform;
}
}
P.S: I have not tested the second one myself for the moment.
You need to make your access specifier to be public to make it accessible
constructor(public service: LoginService) { }
Seems that you're using Ahead-of-Time compilation (while build), and you're trying to access a private member (service) of the component in its template [disabled]="service.loginform.invalid", service.loginform. But it must be public in the case of using it in template and ahead-of-time compilation:
constructor(private service: LoginService) { }
should be:
// your component: change private service to public service
constructor(public service: LoginService) { }
// then you can use it like this in the template of your component:
[formGroup]="service.loginform"
[disabled]="service.loginform.invalid"
If you need a service be private and still need to use some of its members in the template of your component, use get or other methods (public) to return that members:
// your component
constructor(private service: LoginService) { }
get loginForm() {
return this.service.loginform;
}
get loginIsInvalid(): boolean {
return this.service.loginform.invalid;
}
// then in the template of your component you can use:
[formGroup]="loginform"
[disabled]="loginIsInvalid"
Do you have concerns about having to call a function instead of using just a variable in the template?
Catch this self-executing function tip:
Template:
<form class="col-8" [formGroup]="loginform"> <!-- Change here-->
Controller:
import { Component, OnInit } from '#angular/core';
import { LoginService } from '../shared/login.service';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
username : string;
password: string;
hide = true;
constructor(private service: LoginService) { }
ngOnInit() {
}
loginform = (() -> this.service.loginform)(); /* Change here */
}
This can be useful if you need to access some internal fields of that variable inside the template.
<form class="col-8" [formGroup]="loginform.SOME_FIELD.INNER_PROP">
instead of
<form class="col-8" [formGroup]="getLoginForm().SOME_FIELD.INNER_PROP">
It looks more convenient and readable, imho.
So I'm sending a movie object from a parent to a child component. I use #Input from the core module to do this.
Now, I am able to use this data inside the template to display my view, but when I try to access it in for example editReview() then this.movie returns undefined.
Does anyone know how to fix this?
Child Component: the console.log returns undefined
export class ReviewListComponent implements OnInit {
#Input('movie') movie;
constructor(private reviewService: ReviewService){}
editReview() {
console.log(this.movie);
}
}
Child Component Template: I am able to display my name and the content of the review. What's not working unfortunately is when I click the button it says that this.movie is undefined
<ul class="list-group">
<li *ngFor="let review of movie?.reviews" class="list-group-item">
<p>{{review.user.firstName}} {{ review.user.lastName}}</p>
<hr>
<p>{{review.content}}</p>
</li>
</ul>
<button (click)="editReview()">Button</button>
Edit: I added the components and templates of the two parent components: The first one is the movie component where I retrieve the movie object asynchronously, the second is the review component which contains the review-list component that I had already posted above
movie.component.ts
import {Component, OnInit} from "#angular/core";
import { MovieService} from "./movie.service";
import {ActivatedRoute} from "#angular/router";
#Component({
selector: 'app-movie',
templateUrl: './movie.component.html',
styleUrls: ['./movie.component.css']
})
export class MovieComponent implements OnInit{
rating;
movie;
movieId;
constructor(private movieService: MovieService, private route: ActivatedRoute){
}
checkRating(){
return typeof this.rating === 'number';
}
ngOnInit(){
this.route.params.subscribe(params => {
this.movieId = params.id;
var userId = localStorage.getItem('userId');
this.movieService.getMovie(this.movieId)
.subscribe(movie => {
this.movie = movie.obj;
this.movie.averageRating = Number(this.movie.averageRating);
console.log(this.movie);
});
if (userId){
this.movieService.getRating(userId, this.movieId)
.subscribe( result => {
this.rating = result.rating;
})
}
});
}
addRating(score) {
var userId = localStorage.getItem('userId');
this.movieService.addRating(score, userId, this.movie._id)
.subscribe(data => {
this.rating = data.obj.rating;
});
}
}
movie.component.html: this gives movie object to review.component through element app-review
<div class="container">
<div class="col col-md-4 col-md-offset-2">
<img [src]="movie?.pictureUrl" class="img-responsive" alt="hello">
</div>
<div class=" col col-md-6">
<h2>{{movie?.title}} ({{movie?.year}})</h2>
<h3>Average Score:</h3>
<span class="glyphicon glyphicon-star"></span><span><h1>{{movie?.averageRating}}</h1></span><br>
<h3>My Score:</h3>
<div class="row">
<div class="col">
<div *ngIf="!checkRating()" ngbDropdown class="d-inline-block">
<button class="btn btn-outline-primary" ngbDropdownToggle>Rate The Movie!</button>
<div ngbDropdownMenu aria-labelledby="dropdownBasic1">
<button value="1" (click)="addRating(1)" class="dropdown-item">1</button>
<button value="2" (click)="addRating(2)" class="dropdown-item">2</button>
<button value="3" (click)="addRating(3)" class="dropdown-item">3</button>
<button value="4" (click)="addRating(4)" class="dropdown-item">4</button>
<button value="5" (click)="addRating(5)" class="dropdown-item">5</button>
</div>
</div>
<div *ngIf="checkRating()">
<h1>{{rating}}</h1>
</div>
</div>
</div>
<h4>{{movie?.director}}</h4>
<h4>{{movie?.actors}}</h4>
<h4>{{movie?.country}}</h4>
<p> {{movie?.description}}</p>
</div>
</div>
<hr class="col-md-8 col-md-offset-2">
<div class="col-md-8 col-md-offset-2">
<ng-container *ngIf="!!movie">
<app-review [movie]="movie"></app-review>
</ng-container>
</div>
review.component.ts
import {Component, ElementRef, Input, OnInit, ViewChild} from "#angular/core";
import {NgForm} from "#angular/forms";
import {ReviewService} from "./review.service";
import {ActivatedRoute} from "#angular/router";
#Component({
selector: 'app-review',
templateUrl: './review.component.html',
styleUrls: ['./review.component.css']
})
export class ReviewComponent implements OnInit{
movieId;
#Input('movie') movie;
#ViewChild('textArea') textArea;
constructor(private reviewService: ReviewService, private route: ActivatedRoute){}
ngOnInit(){
this.route.params.subscribe( params => {
this.movieId = params.id
});
};
onClear(form: NgForm) {
form.resetForm()
}
onSubmit(form: NgForm) {
let content = form.value.review;
let userId = localStorage.getItem('userId');
let movieId = this.movieId;
this.reviewService.addReview(content, userId, movieId)
.subscribe( result => {
console.log(result.obj);
this.movie.reviews.unshift(result.obj);
form.resetForm()
})
}
}
review.component.html: this gives movie object to the review-list component through app-review-list
<ng-container *ngIf="!!movie">
<app-review-list [movie]="movie"></app-review-list>
</ng-container>
<hr>
<form ngNativeValidate (ngSubmit)="onSubmit(f)" #f="ngForm">
<div class="form-group">
<label for="review">Write A Review:</label>
<textarea
#textArea
(keyup.enter)="onSubmit(f)"
rows="4"
cols="50"
type="text"
id="review"
ngModel
class="form-control"
name="review"
required
></textarea>
</div>
<button type="button" class="btn btn-danger" (click)="onClear(f)">Clear</button>
<button class="btn btn-primary" type="submit">Save</button>
</form>
you can access it in ngOnInit() just implement OnInit interface
I'm developing an app with Angular 2.0/meteor, and I don't know how to bind an input to md-slider.
Here's the component html :
<div class="panel-body">
<form [formGroup]="filtreForm" #f="ngForm">
<span class="panel-title"> <i class="glyphicon glyphicon-retweet"> Paramétrages 0 </i></span>
<md-slide-toggle>On</md-slide-toggle>
<div *ngFor="let filtre of filtres | async">
<div *ngFor="let filtr of filtre.arguments">
<span class="panel-title" > <i class="glyphicon glyphicon-retweet"> {{filtr.name}} </i></span>
<md-input-container class="example-full-width" >
<input mdInput placeholder="{{filtr.name}}" formControlName="{{filtr.name}}" value="{{filtr.value}}">
</md-input-container>
<md-slider
thumb-label
[min]="'0'"
[max]="'200'"
[value]="filtr.value">
</md-slider>
</div>
</div>
<div class="btn-group people-pager">
<button type="button" class="btn btn-success btn-quirk" (click)="appliquerFiltre()"><i class="fa fa-tencent-weibo Try it"></i> Appliquer ce filtre</button>
</div>
</form>
</div>
Here's the component ts :
import {Component, ViewEncapsulation, OnInit, NgZone, Input} from '#angular/core';
import { Router } from '#angular/router';
import { Meteor } from 'meteor/meteor';
import { Observable } from 'rxjs';
import { FormBuilder, FormGroup, Validators } from '#angular/forms';
//Collection import
import { Filtres } from '../../../../both/collections/filtres.collection';
import {Filtre} from "../../../../both/models/filtre.model";
import template from './tpl.dashboard.component.html';
#Component({
selector: 'traitement_par_lot',
encapsulation: ViewEncapsulation.None,
template
})
export class TPLcomponent implements OnInit{
filtres: Observable<Filtre[]>;
filtreForm: FormGroup;
constructor(
private formBuilder: FormBuilder, private router: Router
) {}
ngOnInit(){
this.filtreForm = this.formBuilder.group({
spread:['',Validators.required],
density:['',Validators.required],
curviness:['',Validators.required],
reseed:['',Validators.required],
});
this.filtres = Filtres.find({}).zone();
console.log(this.filtres);
}
appliquerFiltre(){
}
}
This doesn't work. for now i can get the initial value from the slider but it's doesn't change when i slide
Thanks in advance
For update the value while slidering, you can use change or input event of md-slider, and get the current value from it's event.value.
change event will be fired only after the end of you slide.
input event will be fired immediately when the value of slider changes
you can choose the better one for your situation.
take a look at this plunker.