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