在Component Angular 4中使用订阅主题更改检测

时间:2017-08-13 21:08:08

标签: angular

我坚持在服务层内为多个组件设置更改检测。下面我将展示一个组件来说明行为主题的订阅。我没有收到任何错误,只是没有数据显示。 http请求有效。我只使用双向数据绑定,但我需要能够在整个项目中更新多个组件。我认为这个行为主题可能是最好的选择,但我在这里可能是错的。我真的不知道/明白我做错了什么。感谢您提供任何帮助。

问题出在getProjects()函数中。通过订阅get请求,在视图显示之前永远不会调用结果或错误。

@Injectable()
export class ProjectService {
  private projectsUrl: string = Globals.url + '/projects';

  private getProjectsSource = new BehaviorSubject<any>([]);
  getProjectsChange = this.getProjectsSource.asObservable();

  private errorSource = new BehaviorSubject<any>({});
  errorChange = this.errorSource.asObservable;

  private projects: Project[] = [];


  constructor(private http: Http) { }

  getProjects() {
    if (this.projects != null) {
      this.getProjectsSource.next(this.projects);
    }
    else {

      this.http.get(this.projectsUrl, Globals.getTokenHeaders())
        .map(function (res) {
          let data = res.json();

          if (data) {
            for (let project of data.projects) {
              this.projects.push(Project.create(project));
            }
            return this.projects;
          }
        })
        .catch((error: any) => Observable.throw(error || 'Server error'))
        .subscribe(
          result => {
            this.projects = result;
            this.getProjectsSource.next(this.projects);
          },
          error => {
            this.errorSource.next(true);
          });
    }
  }
}

这是订阅服务中行为主题设置的组件。我在构造函数中调用服务的getProjects()方法来触发组件构造的更改。我在ngOnIt函数中订阅了它。

@Component({
  selector: 'app-nav-bar',
  templateUrl: './nav-bar.component.html'
})
export class NavBarComponent implements OnInit {

  projects: Project[] = [];
  projectsFlag: boolean = false;


  constructor(private projectService: ProjectService) {
    this.projectService.getProjects();
  }

  ngOnInit() {
    this.projectService.getProjectsChange.subscribe(result => {
      this.projects = result;
    },
    err => {
        // handle error in template through flag (need to setup flag)
    });
  }
}

编辑: 我获取所有项目一次,但更新或删除等crud ops都在缓存和服务器上更新。因此,当对项目进行更新时,它需要更新作为特定可观察对象的订阅者的每个组件,在这种情况下,我使用行为主题。

1 个答案:

答案 0 :(得分:1)

你有几个问题。最大的问题来自:

if (this.projects != null){}
else {/* http request to get projects */}

else永远不会被触发,因为this.projects不是null。使用

将其设置为空数组
private projects: Project[] = [];

因此,您应该将其设置为null,或者根本不设置它。