Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 从组件调用模型方法时,错误不是函数_Angular_Typescript - Fatal编程技术网

Angular 从组件调用模型方法时,错误不是函数

Angular 从组件调用模型方法时,错误不是函数,angular,typescript,Angular,Typescript,当我试图从组件模板调用model方法时,我遇到了这个错误 error in ./NewsListComponent class NewsListComponent - inline template:3:12 caused by: self.context.$implicit.toggleState 我从API获得消息,可以在我的组件模板上看到消息。然后我尝试添加一个(单击)事件,并从消息中调用toggleState()方法。我只是在英雄之旅之后做点什么 这里我展示一些代码 news.mod

当我试图从组件模板调用model方法时,我遇到了这个错误

error in ./NewsListComponent class NewsListComponent - inline template:3:12 caused by: self.context.$implicit.toggleState
我从API获得消息,可以在我的组件模板上看到消息。然后我尝试添加一个(单击)事件,并从消息中调用toggleState()方法。我只是在英雄之旅之后做点什么

这里我展示一些代码


news.model.ts

export class News {
    constructor(
        id: number,
        title: string,
        news: string,
        path: string,
        date: Date,      
        public state = 'inactive',
    ) {}

    public toggleState()
    {
        this.state = (this.state === 'active' ? 'inactive' : 'active');
    }
}
import { Injectable }       from '@angular/core';
import { Http, 
         Response, 
         Headers, 
         RequestOptions }   from '@angular/http';

import { Observable }       from 'rxjs/Observable';

import { News }             from './news.model';

@Injectable()
export class NewsService {
    private url = 'http://127.0.0.1:8000/app_dev.php/news';

    constructor(private http:Http){}

    getNews(): Observable<News[]> {
        let headers = new Headers({
            'Content-Type': 'application/json'
        });
        let options = new RequestOptions({
            headers: headers
        });
        return this.http
                    .get(this.url, options)
                    .map(this.extractData)
                    .catch(this.handleError);                    
    }

    private handleError (error: Response | any) {
        // In a real world app, we might use a remote logging infrastructure
        let errMsg: string;
        if (error instanceof Response) {
            const body = error.json() || '';
            const err = body.error || JSON.stringify(body);
            errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
        } else {
            errMsg = error.message ? error.message : error.toString();
        }
        console.error(errMsg);
        return Observable.throw(errMsg);
    }

    private extractData(res: Response) {
        let body = res.json()
        return body || { };
    }   
}
import { 
    Component, 
    OnInit, 
    Input,
    trigger,
    state,
    style,
    transition,
    animate }           from '@angular/core';

import { News }         from './news.model';
import { NewsService }  from './news.service';

@Component({
    selector: 'news-list',   
    template: `
        <div class="col-sm-8">
            <h2>Noticias</h2>
            <div class="media" *ngFor="let news_ of news" 
                [@newsState]="news_.state"
                (click)="news_.toggleState()">
                <div class="media-right media-middle">
                    <a href="#">
                        IMG
                    </a>
                </div>
                <div class="media-body media-middle">
                <h4 class="media-heading">{{news_.title}}</h4>
                <p>{{news_.news}}</p>
                <hr>
                </div>
            </div>
        </div>        
    `,
    animations: [
        trigger('newsState', [
        state('inactive', style({
            backgroundColor: '#eee',
            transform: 'scale(1)'
        })),
        state('active',   style({
            backgroundColor: '#cfd8dc',
            transform: 'scale(1.1)'
        })),
        transition('inactive => active', animate('100ms ease-in')),
        transition('active => inactive', animate('100ms ease-out'))
        ])
    ],
})
export class NewsListComponent implements OnInit {
    error: string;
    @Input() news: News[];
    mode = 'Observable';
    constructor(private newsService: NewsService) {;
    }

    ngOnInit() {        
        this.newsService.getNews()
            .subscribe(
                (news: News[]) => this.news = news,
                error => this.error = <any>error
            );
    }
}
import { NgModule }             from '@angular/core';
import { CommonModule }         from '@angular/common';

import { NewsService }          from './news.service';
import { NewsListComponent }    from './news-list.component';

@NgModule({
    imports: [
        CommonModule,  
    ],
    declarations: [
        NewsListComponent        
    ],
    providers: [
        NewsService
    ],
    exports: [
        NewsListComponent
    ],        
})

export class NewsModule {}
新闻服务.ts

export class News {
    constructor(
        id: number,
        title: string,
        news: string,
        path: string,
        date: Date,      
        public state = 'inactive',
    ) {}

    public toggleState()
    {
        this.state = (this.state === 'active' ? 'inactive' : 'active');
    }
}
import { Injectable }       from '@angular/core';
import { Http, 
         Response, 
         Headers, 
         RequestOptions }   from '@angular/http';

import { Observable }       from 'rxjs/Observable';

import { News }             from './news.model';

@Injectable()
export class NewsService {
    private url = 'http://127.0.0.1:8000/app_dev.php/news';

    constructor(private http:Http){}

    getNews(): Observable<News[]> {
        let headers = new Headers({
            'Content-Type': 'application/json'
        });
        let options = new RequestOptions({
            headers: headers
        });
        return this.http
                    .get(this.url, options)
                    .map(this.extractData)
                    .catch(this.handleError);                    
    }

    private handleError (error: Response | any) {
        // In a real world app, we might use a remote logging infrastructure
        let errMsg: string;
        if (error instanceof Response) {
            const body = error.json() || '';
            const err = body.error || JSON.stringify(body);
            errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
        } else {
            errMsg = error.message ? error.message : error.toString();
        }
        console.error(errMsg);
        return Observable.throw(errMsg);
    }

    private extractData(res: Response) {
        let body = res.json()
        return body || { };
    }   
}
import { 
    Component, 
    OnInit, 
    Input,
    trigger,
    state,
    style,
    transition,
    animate }           from '@angular/core';

import { News }         from './news.model';
import { NewsService }  from './news.service';

@Component({
    selector: 'news-list',   
    template: `
        <div class="col-sm-8">
            <h2>Noticias</h2>
            <div class="media" *ngFor="let news_ of news" 
                [@newsState]="news_.state"
                (click)="news_.toggleState()">
                <div class="media-right media-middle">
                    <a href="#">
                        IMG
                    </a>
                </div>
                <div class="media-body media-middle">
                <h4 class="media-heading">{{news_.title}}</h4>
                <p>{{news_.news}}</p>
                <hr>
                </div>
            </div>
        </div>        
    `,
    animations: [
        trigger('newsState', [
        state('inactive', style({
            backgroundColor: '#eee',
            transform: 'scale(1)'
        })),
        state('active',   style({
            backgroundColor: '#cfd8dc',
            transform: 'scale(1.1)'
        })),
        transition('inactive => active', animate('100ms ease-in')),
        transition('active => inactive', animate('100ms ease-out'))
        ])
    ],
})
export class NewsListComponent implements OnInit {
    error: string;
    @Input() news: News[];
    mode = 'Observable';
    constructor(private newsService: NewsService) {;
    }

    ngOnInit() {        
        this.newsService.getNews()
            .subscribe(
                (news: News[]) => this.news = news,
                error => this.error = <any>error
            );
    }
}
import { NgModule }             from '@angular/core';
import { CommonModule }         from '@angular/common';

import { NewsService }          from './news.service';
import { NewsListComponent }    from './news-list.component';

@NgModule({
    imports: [
        CommonModule,  
    ],
    declarations: [
        NewsListComponent        
    ],
    providers: [
        NewsService
    ],
    exports: [
        NewsListComponent
    ],        
})

export class NewsModule {}
我做错了什么? 提前谢谢


编辑:似乎
News[]
中没有真正填充新闻对象,如果显式创建新闻对象,则不会出现错误


问题已由AJT_解决82谢谢

ngOnInit() { 
    this.newservice.getNews()
        .subscribe(data => {
            data.forEach(n => {
                let newsObj: News = new News(n.id, n.title, n.news, n.path, n.date);
                this.news.push(newsObj);
            })
        });
}

只需稍微更改一下您的订阅即可解决此问题,如下所示:

ngOnInit() { 
    this.newservice.getNews()
        .subscribe(data => {
            data.forEach(n => {
                let newsObj: News = new News(n.id, n.title, n.news, n.path, n.date);
                this.news.push(newsObj);
            })
        });
}
这样,每个新闻都将是
news
的一个实例,并具有适当的方法,例如您的toggleState方法


希望这有帮助

我如何用可观测数据来解决这个问题?不客气,很高兴我能帮上忙!如果你能通过点击投票下面的勾号接受我的答案,我会更高兴:P