通过适当的更改跟踪将服务属性绑定到组件属性 [英] Bind a service property to a component property with proper change tracking

查看:61
本文介绍了通过适当的更改跟踪将服务属性绑定到组件属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑完全简单的Angular 2服务:

Consider the utterly simple Angular 2 service:

import { Injectable } from '@angular/core';
import {Category} from "../models/Category.model";

@Injectable()
export class CategoryService {
    activeCategory: Category|{} = {};
    constructor() {};
}

然后使用该服务的组件:

And then the component using this service:

import { Component, OnInit } from '@angular/core';
import {CategoryService} from "../shared/services/category.service";
import {Category} from "../shared/models/Category.model";

@Component({
    selector: 'my-selector',
    template: `
    {{categoryService.activeCategory.Name}}<br/>
    {{category.Name}}<br/>
`,
})
export class MySelectorComponent implements OnInit {
    category:Category|{} = {};

    constructor(public categoryService:CategoryService){};

    ngOnInit() {
        this.category = this.categoryService.activeCategory;
    };
}

假定适当定义的Category模型,并假定某个位置的另一个组件将服务上的activeCategory设置为有效的Category.假设将categoryservice设置为更高级别的提供者.

Assume appropriately defined Category model and assume that another component somewhere sets the activeCategory on the service to a valid Category at some point. Assume that the categoryservice is set as provider at an appropriately higher level.

发生这种情况时,模板中的第一行将正确显示类别名称,但第二行则不会.我已经尝试过在服务上使用getters和setters vs. raw访问.我已经尝试过原始类型与对象与对象属性的比较.我不敢相信第一行是这种类型的访问的合适范例.有人可以告诉我将服务属性绑定到组件属性的最简单方法,该方法将正确地进行角度2的更改跟踪吗?

When that happens, the first line in the template will correctly display the category Name, but the second line will not. I've tried using getters and setters vs. raw access on the service; I've tried primitive types vs. objects vs. object properties; I can't believe that the first line is the appropriate paradigm for this type of access. Can someone tell me the simplest way to bind a service property to a component property that will properly do change tracking in angular two?

澄清:我知道我可以使用自己创建并推送给自己的可观察对象.我要问的是,是否有任何形式的框架已经熟透了(不需要我为观察到的东西编写大量的样板文件),而这只是在服务和组件之间建立了一个可变的轨道.

CLARIFICATION: I know I could use observables that I create and push to for myself. What I am asking is if there is any kind of already-baked into the framework way of doing this (that doesn't require me to write the huge amount of boilerplate for an observable) that just makes a variable track between the service and component.

推荐答案

Observable s使用Behavior s无需太多样板即可使用.

Observables can be used without much boilerplate using Behaviors.

@Injectable() 
export class CategoryService {
  activeCategory:BehaviorSubject<{category:Category}> = new BehaviorSubject({category:null});
  // or just `Subject` depending on your requirements
}

@Component({
  selector: 'my-selector',
  template: `
  {{(categoryService.activeCategory | async)?.Name}}<br/>
`,
})
export class MySelectorComponent implements OnInit {
  constructor(public categoryService:CategoryService){};
}

您还可以仅绑定到服务的属性

You also can just bind to properties of your service

@Component({
  selector: 'my-selector',
  template: `
  {{categoryService?.activeCategory?.Name}}<br/>
`,
})
export class MySelectorComponent implements OnInit {
  constructor(public categoryService:CategoryService){};
}    

使用猫王(或安全导航)操作员,如果activeCategory之后才获得值(例如,异步调用完成时),则不会出错.

Using the Elvis (or safe-navigation) operator you don't get an error if the activeCategory only gets a value later, for example when an async call completes.

这篇关于通过适当的更改跟踪将服务属性绑定到组件属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆