【问题标题】:Angular2 Observable not rendering until data changedAngular2 Observable 在数据更改之前不会渲染
【发布时间】:2016-10-12 10:59:18
【问题描述】:

我是 Angular2 的新手,所以希望我有一个简单的问题可以解决 :)

我正在尝试使用可观察服务在多个视图(即单独的路由)之间共享数据(对象列表,由服务本地存储在内存中)。问题是,当我更改路线(即通过链接)时,共享数据不会呈现,直到我将新项目“添加”到列表中(即在当前路线中)。我见过很多类似的堆栈溢出问题,但没有一个解决方案完全奏效。

我不知道错误是在我的路由、我的 ngInit 函数(即在数据完成之前渲染?)还是在我自己定义服务/组件的方式中。这里有一些代码sn-ps来说明:

路由:

const appRoutes: Routes = [
  {
    path: '',
    redirectTo: '/running-order',
    pathMatch: 'full'
  },
  {
    path: 'running-order',
    component: RunningOrderComponent
  },
  {
    path: 'enquiry',
    component: EnquiryComponent
  },
  {
    path: 'config',
    component: ConfigComponent
  }
];

export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);

服务:

@Injectable()
export class ChaptersService{

    //Observable Source
    private chaptersSource:Subject<BaseChapter[]>;

    //Observable Stream
    chapters$: Observable<BaseChapter[]>;

    //DataStore
    private dataStore:{ chapters: BaseChapter[] };

    constructor() {
        console.log('chapter service instantiated');
        this.chaptersSource = new Subject<BaseChapter[]>();
        this.chapters$ = this.chaptersSource.asObservable();
        this.dataStore = { chapters: [] };      
    }

    loadAll() {
        this.chaptersSource.next(this.dataStore.chapters);
    }

    addChapter(data:BaseChapter){
        this.dataStore.chapters.push(data);
        this.chaptersSource.next(this.dataStore.chapters);
    }
}   

组件(路由):

@Component({
    selector: 'myenquiry',
    templateUrl: 'enquiry.component.html',
    styleUrls: ['enquiry.component.css']
})

export class EnquiryComponent implements OnInit{
    config : Config;
    title = 'Enquiry Angular App';
    selectedChapter: BaseChapter;

    chapters$: Observable<BaseChapter[]>;

    constructor(private chaptersService:ChaptersService){}

    ngOnInit():void {
        this.chaptersService.loadAll();
        this.chapters$ = this.chaptersService.chapters$;
        console.log('enquiry component initialised...');
    }

    onSelect(chapter: BaseChapter): void {
      this.selectedChapter = chapter;
    }

    addChapter():void {
        var chapter:Chapter = new Chapter(0);
        chapter.initChapter("untitled",4);
        this.chaptersService.addChapter(chapter);
        this.selectedChapter = chapter;
    }
}

组件模板:

<h2>List of Chapters</h2>
<ul class="chapters">
    <li *ngFor="let chapter of chapters$ | async" [class.selected]="chapter === selectedChapter" (click)="onSelect(chapter)" >
        <span class="idStyle">{{chapter.id}}</span> {{chapter.name}}
    </li>
</ul>
<chapter [chapterData]="selectedChapter"></chapter>
<button (click)="addChapter()">Add Chapter</button>

谢谢,菲尔。

【问题讨论】:

  • 尝试使用BehaviorSubject,它有你可以指定的默认值。
  • @Sasxa 这并不是说我需要默认显示,我的意思是即使有数据也不会出现任何内容,直到添加另一个项目。即每次您返回路线时,它都是空白的,直到您添加另一个项目,然后所有项目都显示出来......
  • 更改私人章节Source:Subject;成为一个重播主题,这样如果可观察对象在您的组件绑定之前获得一个值,它将获得最后一个推送的值。
  • @PaulSwetz 看起来好像奏效了!如果您想将您的评论变成答案,我会投票/标记为解决方案?
  • 完成,感谢投票

标签: angular angular2-routing angular2-services


【解决方案1】:

改变

private chaptersSource:Subject<BaseChapter[]>; 

成为

private chaptersSource:ReplaySubject<BaseChapter[]>;

这样,如果 observable 在你的组件绑定之前获得一个值,它将获得最后一个推送的值。

【讨论】:

    猜你喜欢
    • 2017-06-09
    • 2016-06-09
    • 1970-01-01
    • 1970-01-01
    • 2016-08-20
    • 2017-01-06
    • 2013-04-24
    • 1970-01-01
    相关资源
    最近更新 更多