var / const的角度损失

时间:2017-11-22 11:06:17

标签: angular scope var let scoping

我正在制作一个简单的休息todo-crud应用程序角度(确切地说是5)。

我对范围有问题(或者更确切地说是问题)(或者​​我认为它是什么):

home.component.ts:

import { Component, OnInit } from '@angular/core';
import { HomeService } from './service/home.service';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {

  itemCount: number = 0;
  todo = [];
  addingVar: Object;
  dueDate: string;
  constructor(private homeService: HomeService) { }

  ngOnInit() {
    let ltodo = []; // ADDED THIS TO FORCE VALUE STORAGE
    this.homeService.getToDo().subscribe(
      function(response) {
        ltodo = response;
      },
      function(error) { console.log('Error happened', error); },
      function() { }
    );
    setTimeout(function(){ // <-HACK TO FORCE IT TO STORE DATA AT LEAST WITHIN "ngOnInit"
                           // I'LL USE A DEBOUNCED FUNCTION INSTEAD LATER
      this.todo = ltodo;
      this.itemCount = this.todo.length;
      console.log(this.todo);      // <- (array of 9 objects) works!!
      console.log(this.itemCount); // <- 9                    works!!
    }, 10);
  }

  addItem() {
    console.log(this.todo); // <- this.todo IS NOW EMPTY ARRAY! WHY??
    this.addingVar = {name: this.todoTitle, description: this.todoText, date: Date.now(), dueDate: this.dueDate };
    console.log(this.addingVar);
    this.homeService.postToDo(this.addingVar).subscribe(
      function(response) { console.log('Success Response', response); },
      function(error) { console.log('Error happened', error); },
      function() { }
    );
  }
}

home.service.ts:

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import 'rxjs/add/operator/map';

@Injectable()
export class HomeService {
  constructor (
    private http: Http
  ) {}
  getToDo() {
      return this.http.get(`http://localhost:3000/todos`)
        .map((res: Response) => res.json());
  }
  getToDoId(id: string) {
    return this.http.get(`http://localhost:3000/todos/${id}`)
      .map((res: Response) => res.json());
  }
  postToDo(body: object) {
    return this.http.post(`http://localhost:3000/todos`, body)
      .map((res: Response) => res.json());
  }
  putToDoId(id: string, body: object) {
    return this.http.put(`http://localhost:3000/todos/${id}`, body)
      .map((res: Response) => res.json());
  }
  deleteToDoId(id: string) {
    return this.http.delete(`http://localhost:3000/todos/${id}`)
      .map((res: Response) => res.json());
  }
}

我无法弄清楚我应该如何拥有可用的vars / lets / const

我做错了什么?为什么,在我的第一个函数(应用程序加载时调用)中,我是否有一个水合变量而在我的第二个函数中(由于我必须单击一个按钮才能调用它,因此必须调用),我的var未水化??? :

enter image description here

还有为什么我被推到这个本地var + wait / debounce gimmick以获得响应函数的响应?

必须有更好的方法。

3 个答案:

答案 0 :(得分:1)

您无需使用setTimeout等待来自服务器的响应,事实上,您subscribe已经检索到了值,所以只需:

ngOnInit() {
this.homeService.getToDo().subscribe(
  response => this.todos = response // sufficient
  error =>  console.log('Error happened', error) // use lamdas to preserve `this`
  }

答案 1 :(得分:0)

在ngOnInit中你的应用程序不会等forthis.homeService.getToDo()结束。它运行其余的方法,每当您的请求完成时,它会为您订阅它的功能。 因此在获取结果之前调用this.todo = ltodo;

答案 2 :(得分:0)

您的回调中丢失了this。您需要使用箭头功能或将this绑定到回调。

setTimeout(() => { // <-HACK TO FORCE IT TO STORE DATA AT LEAST WITHIN "ngOnInit"
                           // I'LL USE A DEBOUNCED FUNCTION INSTEAD LATER
      this.todo = ltodo;
      this.itemCount = this.todo.length;
      console.log(this.todo);      // <- (array of 9 objects) works!!
      console.log(this.itemCount); // <- 9                    works!!
    }, 10);`

setTimeout((function(){ // <-HACK TO FORCE IT TO STORE DATA AT LEAST WITHIN "ngOnInit"
                       // I'LL USE A DEBOUNCED FUNCTION INSTEAD LATER
  this.todo = ltodo;
  this.itemCount = this.todo.length;
  console.log(this.todo);      // <- (array of 9 objects) works!!
  console.log(this.itemCount); // <- 9                    works!!
}).bind(this), 10);

将做你需要的。 箭头函数可以访问父上下文,而function(){}声明不能没有障碍。