Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/32.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
Javascript 为什么可观测变量的变化会触发视角的变化_Javascript_Angular - Fatal编程技术网

Javascript 为什么可观测变量的变化会触发视角的变化

Javascript 为什么可观测变量的变化会触发视角的变化,javascript,angular,Javascript,Angular,我正在学习Angular,所以我正在构建todo应用程序。TODO是从API中提取的,它们中的每一个都有一个作为父项的项目。在一个视图中,我添加了一个新的项目,它在服务中触发addNewProject方法,该方法反过来又在另一个服务中触发对API的POST请求。项目列在侧栏中,绑定到来自父组件的输入。ProjectsService在一个私有字段中保存一系列项目,并具有可观察性,主要组件使用这些项目 我很难理解为什么在服务中的API调用之后追加私有属性项目会触发MainComponent属性的更改

我正在学习Angular,所以我正在构建todo应用程序。TODO是从API中提取的,它们中的每一个都有一个作为父项的项目。在一个视图中,我添加了一个新的项目,它在服务中触发addNewProject方法,该方法反过来又在另一个服务中触发对API的POST请求。项目列在侧栏中,绑定到来自父组件的输入。ProjectsService在一个私有字段中保存一系列项目,并具有可观察性,主要组件使用这些项目

我很难理解为什么在服务中的API调用之后追加私有属性项目会触发MainComponent属性的更改,即使这些项目是私有的,并且数组中的Observable的更改不应该触发从观察者传递的函数

家长:

@Component({
  selector: 'app-main',
  templateUrl: './main.component.html',
  styleUrls: ['./main.component.css']
})
export class MainComponent implements OnInit {
  projects: Project[] = new Array<Project>();

  constructor(private projectsService: ProjectsService) {
  }

  ngOnInit() {
    this.projectsService.projects$.subscribe((projects) => {
      this.projects = projects;
    });
  }

  addNewProject(newProjectName: string) {
    this.projectsService.addNewProject(newProjectName);
  }

}
@组件({
选择器:'应用程序主',
templateUrl:'./main.component.html',
样式URL:['./main.component.css']
})
导出类MainComponent实现OnInit{
项目:项目[]=新数组();
建造商(私人项目服务:项目服务){
}
恩戈尼尼特(){
this.projectsService.projects$.subscribe((projects)=>{
这个项目=项目;
});
}
addNewProject(newProjectName:string){
this.projectsService.addNewProject(newProjectName);
}
}
侧栏:

@Component({
  selector: 'app-sidebar',
  templateUrl: './sidebar.component.html',
  styleUrls: ['./sidebar.component.css']
})
export class SidebarComponent implements OnInit {
  @Input() projects: Project[];
  @Output() projectEntered = new EventEmitter<string>();

  constructor() {
  }

  ngOnInit() {
  }

  projectAdded(projectName: string) {
    this.projectEntered.emit(projectName);
  }

}
@组件({
选择器:“应用程序侧栏”,
templateUrl:'./sidebar.component.html',
样式URL:['./sidebar.component.css']
})
导出类SidebarComponent实现OnInit{
@输入()项目:项目[];
@Output()projectEntered=neweventemitter();
构造函数(){
}
恩戈尼尼特(){
}
已添加项目(项目名称:字符串){
this.projectEntered.emit(projectName);
}
}
服务:

export class ProjectsService {

  private _projects$: Observable<Array<Project>> = new Observable<Array<Project>>();
  private _projects: Project[] = [];
  private _loadedProject$: Observable<Project>;
  private _projectsLoaded: boolean;
  private _taskForProject: object;

  constructor(private userService: UserService, private api: ApiService) {
  }

  loadAllProjects() {

    this._projects$ = this.api.getAllProjectsByUserId(this.userService.userId).pipe(
      map((projects) => {
        this._projects = projects;
        return this._projects;
      })
    );
  }

  get projects$() {
    if (!this._projectsLoaded) {
      this.loadAllProjects();
    }
    return this._projects$;
  }

  getAllTasks() {
    return this.api.getAllTasksByUserId(this.userService.userId);
  }

  getProject(projectId: string) {
    this._loadedProject$ = this.api.getProjectById(projectId);
    return this._loadedProject$;
  }

  getTodayTasksForProject(tasks: Task[]) {
    const todayTasks: Task[] = [];
    const todayDate = new Date();
    tasks.forEach((task) => {
      if (new Date(task.completionPlannedDate).getDate() === todayDate.getDate()) {
        tasks.splice(tasks.indexOf(task), 1);
        todayTasks.push(task);
      }
    });
    return todayTasks;
  }

  getTomorrowTasksForProject(tasks: Task[]) {
    const tomorrowTasks: Task[] = [];
    const tomorrowDate = new Date(new Date().getDate() + 1);
    tasks.forEach((task) => {
      if (new Date(task.completionPlannedDate).getDate() === tomorrowDate.getDate()) {
        tasks.splice(tasks.indexOf(task), 1);
        tomorrowTasks.push(task);
      }
    });
    return tomorrowTasks;
  }

  getUpcomingTasks(tasks: Task[]) {
    const upcomingTasks: Task[] = [];
    const upcomingDate = new Date(new Date().getDate() + 2);
    tasks.forEach((task) => {
      if (new Date(task.completionPlannedDate).getDate() > upcomingDate.getDate()) {
        tasks.splice(tasks.indexOf(task), 1);
        upcomingTasks.push(task);
      }
    });
    return upcomingTasks;
  }

  addNewProject(projectName: string) {
    this.api.postNewProject({
      id: null,
      userId: this.userService.userId,
      title: projectName,
      tasks: []
    }).subscribe((project: Project) => {
      this._projects.push(project);
    });
  }
}
导出类项目服务{
private_projects$:Observable=新Observable();
私人项目:项目[]=[];
私有_loadedProject$:可观察;
private\u projectsLoaded:布尔值;
private\u taskForProject:对象;
构造函数(私有userService:userService,私有api:ApiService){
}
loadAllProjects(){
this.\u projects$=this.api.GetAllProjectsBySerid(this.userService.userId).pipe(
地图((项目)=>{
这是._projects=projects;
将此返回。\u项目;
})
);
}
获取项目$(){
如果(!this.\u projectsLoaded){
这是loadAllProjects();
}
将此返回。_projects$;
}
getAllTasks(){
返回this.api.getAllTasksBySerid(this.userService.userId);
}
getProject(projectId:string){
this.\u loadedProject$=this.api.getProjectById(projectId);
返回此项目。_loadedProject$;
}
GetToDayTaskForProject(任务:任务[]){
const today任务:任务[]=[];
const todayDate=新日期();
tasks.forEach((任务)=>{
if(新日期(task.completionPlannedDate).getDate()==todayDate.getDate()){
tasks.splice(tasks.indexOf(task),1);
今天的任务。推送(任务);
}
});
返回今天的任务;
}
getTomorrowTasksForProject(任务:任务[]){
consttomorrowtasks:Task[]=[];
const tomorrowDate=新日期(new Date().getDate()+1);
tasks.forEach((任务)=>{
if(新日期(task.completionPlannedDate).getDate()==明天日期.getDate()){
tasks.splice(tasks.indexOf(task),1);
明天的任务。推送(任务);
}
});
明天返回任务;
}
getUpcomingTasks(任务:任务[]){
const upcomingTasks:Task[]=[];
const upcomingDate=新日期(新日期().getDate()+2);
tasks.forEach((任务)=>{
if(新日期(task.completionPlannedDate).getDate()>upcomingDate.getDate()){
tasks.splice(tasks.indexOf(task),1);
upcomingTasks.push(任务);
}
});
返回即将到来的任务;
}
addNewProject(项目名称:字符串){
this.api.postNewProject({
id:null,
userId:this.userService.userId,
标题:项目名称,
任务:[]
}).订阅((项目:项目)=>{
此._projects.push(项目);
});
}
}
请参见:

基本上,应用程序状态的更改可以由三个因素引起:

  • 事件-单击,提交
  • XHR-从远程服务器获取数据
  • 计时器-setTimeout(),setInterval()
如果不想将“更改检测”更改为“火灾”,请尝试将更改为