Angular不会分配另一个的trytry值

时间:2019-03-03 19:25:07

标签: javascript angular typescript

最近我开始学习Angular,但是今天我遇到了一个问题。我有以下组件:

import { Component, OnInit } from '@angular/core';
import { SharedService } from '../home/shared.service';
import { IData } from '../data/IData';

@Component({
  selector: 'app-current-article',
  templateUrl: './current-article.component.html',
  styleUrls: ['./current-article.component.css']
})
export class CurrentArticleComponent implements OnInit {

  data: IData;
  symbols: number = 150;
  showReadMore = true;
  contentToShow: string = "";

  constructor(private _sharedService: SharedService) { }

  ngOnInit() {
    this.data = this._sharedService.sharedData;
    this.contentToShow = this.data.content;
  }

  readMore() {
    //this.symbols += 100;
  }
}

“数据”属性是具有以下属性的对象:标题(字符串),authorId(数字)和内容(字符串)。

我还遵循this post的解决方案并提供了这项服务:

import { Injectable } from '@angular/core';
import { IData } from '../data/IData';

@Injectable()
export class SharedService{

    sharedData: IData = {
        title: "",
        authorID: 0,
        content: ""
    };

    insertData(data: IData){
        this.sharedData.title = data.title;
        this.sharedData.authorID = data.authorID;
        this.sharedData.content = data.content;
    }
}

我也有该组件的视图:

<div *ngIf="data.title">
    <h1>{{ data.title }}</h1>
    <h5>Author ID: {{ data.authorID }}</h5>
    <div>
        <span>{{ contentToShow }} </span>
        <span>
            <a href="#" *ngIf="showReadMore" (click)="readMore()">Read More &#8618;</a>
        </span>
    </div>
</div>

这是我的问题。 “ contentToShow”属性似乎未定义,我发现这很奇怪...但是,如果我尝试使用“ data.content”,它可以正常工作并显示我的数据。怎么了?我想解决2个小时,我开始认为它一定很明显,但是我不知道是什么...谢谢!

4 个答案:

答案 0 :(得分:3)

在您将data.content的值分配给contentToShow时,该属性未设置,因此似乎未设置contentToShow。您需要知道Javascript可与“按引用调用”一起使用,但仅适用于数组或对象,不适用于基本体(例如字符串,数字等)。

因此,在使用data.content时您会看到一些价值。因为您直接从对象访问属性,并且更改的值显示在html中。

为更好地理解这篇文章,Is JavaScript a pass-by-reference or pass-by-value language?可以提供帮助。

解决问题的两种方法可以是:您可以使用data.content,也可以通知组件值已更改,例如通过使用Observable。

最后一个看起来像这样:

@Injectable()
export class SharedService{
    notfiySubject: Subject< IData > = new Subject();

    ...
    insertData(data: IData){
        this.sharedData.title = data.title;
        this.sharedData.authorID = data.authorID;
        this.sharedData.content = data.content;
        // Emits the subject
        this.notifySubject.next(this.sharedData);
    }
}

在您的组件中,您将订阅该主题:

this._sharedService.notifySubject.subscribe(data => {
    // Here you can set `contentToShow` with data or _sharedServices.sharedData
});

答案 1 :(得分:0)

问题在于您的“ contentToShow”是原始类型(字符串),并且已在ngOnInit中初始化(并且仅在此位置)。更新sharedData后,它会正确更新,但是contentToShow和this.data.content之间的连接会丢失。其实不在那里。

所以这永远都行不通:

<span>{{ contentToShow }} </span>

相反,您必须像这样从dataService保留对对象的引用:

<span>{{ data.content }} </span>

更新: 如果您仍想使用“ contentToShow”来自定义输出,那么您必须获得有关更改的通知。一种方法是在您的“ dataService”中添加一个Subject,如下所示:

dataChanged = new Subject<any>();

此主题到位后,您可以以此作为最后一行来更新“ insertData”方法:

    this.sharedData.content = data.content;
    this.dataChanged.next(); // <-- this will send the notification
}

在您的“ CurrentArticleComponent”(ngOnInit)中,您需要订阅此通知并像这样更新“ contentToShow”:

this._sharedService.dataChanged.subscribe(() => {
  this.contentToShow = '??? ' + this.sharedService.sharedData.content + ' ???';
})

StackBlitz

答案 2 :(得分:0)

基于此answer,它使用了类似的解决方案,但是OP的代码存在以下问题:

this.contentToShow = this.data.content;

不起作用,因为它不像上面的示例中那样引用对象datathis.contentToShowstring,每次数据被_sharedService更改时,它都不知道这些更改,这与像这样{{1} }。现在this.data = this._sharedService.sharedDatathis.data都指向同一个对象。

  

但是,如果我尝试使用“ data.content”,它就可以正常工作并显示我的数据。

之所以起作用,是因为组件使用对同一对象的引用并在发生更改时进行更新。

因此该解决方案在component.ts和模板中使用this._sharedService.sharedData

this.data

答案 3 :(得分:-1)

http通话本质上是asyn

让我解释一下。最初,您将contentToShow的值设置为"",这是一个空字符串,并且适合角度,但是在ngOnInit()调用中,您设置了this.contentToShow = this.data.content

可能未设置this._sharedService.sharedData或正在等待服务器响应,而对于data: IData;的初始值也可能未定义,因此this.data.content将是undefinedngOnInit()通话之后。

要解决此错误,只有以下代码可用this.contentToShow时,您才能在init方法中设置the this.data.content

设置您的初始数据和内容:

 data: IData = { content: '' };

,否则您可以在init调用中将其设置为''

ngOnInit() {
    this.data = this._sharedService.sharedData;
    this.contentToShow = this.data && this.data.content || '';
}