【问题标题】:Angular: @Input value available in template, but not in componentAngular:@Input 值在模板中可用,但在组件中不可用
【发布时间】:2018-03-01 13:29:20
【问题描述】:

所以我将电影对象从父组件发送到子组件。我使用核心模块中的 @Input 来执行此操作。

现在,我可以在模板中使用这些数据来显示我的视图,但是当我尝试在例如editReview() 中访问它时,this.movie 返回未定义。

有谁知道如何解决这个问题?

子组件:console.log 返回 undefined

export class ReviewListComponent implements OnInit {
@Input('movie') movie;

constructor(private reviewService: ReviewService){}

editReview() {
    console.log(this.movie);
}

}

子组件模板:我可以显示我的姓名和评论内容。不幸的是,当我单击按钮时,它显示 this.movi​​e 未定义

<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>

编辑:我添加了两个父组件的组件和模板:第一个是我异步检索电影对象的电影组件,第二个是包含我的评论列表组件的评论组件上面已经发过了

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:这通过元素 app-review 将电影对象提供给 review.component

<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:这会将电影对象通过 app-review-list 提供给 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>

【问题讨论】:

  • 试试这个:@Input() movie;
  • 仍然未定义:/
  • 你能在 ngOnInit(){ console.log(movie); 中访问电影吗? } ?
  • 你能显示父母的html代码,你在哪里分配电影属性?
  • Carton,是的,这样我就可以访问电影对象了。

标签: javascript angular


【解决方案1】:

您可以在 ngOnInit() 中访问它,只需实现 OnInit 接口

【讨论】:

  • 我可以在 ngOnInit() 中访问它,但不能在 editReview() 方法中访问。
猜你喜欢
  • 2018-04-30
  • 2015-10-13
  • 1970-01-01
  • 2018-10-15
  • 2022-08-05
  • 1970-01-01
  • 2013-05-16
  • 1970-01-01
  • 2021-08-18
相关资源
最近更新 更多