2016-07-26 76 views
2

不知道我在这里失踪。ES6和承诺内的变量范围

我需要得到data的输出为this.contact。现在,我正在使用一个静态类变量,但它似乎很脏,必须这样做。

export class contactEdit { 
    static t; // static class var 
    constructor() { 
    this.id = null; 
    this.contact = null; 
    contactEdit.t = this; 
    } 

    activate(id) { 
    this.id = id; 
    let contact = this.contact; // scoped version of class var 
    return dpd.contacts.get(id).then(function(data) { 
     console.log(data); 
     contactEdit.t.contact = data; // this works 
     contact = data; // this doesn't 
    }); 
    } 
} 

通常我会创造一个var contactactivate()功能(它适用于Chrome控制台)内,但这个似乎并没有在ES6工作确实。

Chrome的控制台:

var c = null; 
undefined 
c; 
null 
dpd.contacts.get('a415fdc8f5a7184d').then(function(data) { 
     c = data; 
    }); 
Object {}fail: (n)then: (e,t)__proto__: Object 
c; 
Object {firstName: "John", lastName: "Doe", id: "a415fdc8f5a7184d"} 
+1

你没只想'this.contact =数据;',而不是'接触=数据;'? – trincot

+0

'static t;'不是ES6。你使用打字稿还是什么? – Bergi

+2

无论如何,您都不应该将承诺结果存储为实例属性。如果需要,请保存承诺。 – Bergi

回答

13

你需要做两件事情。首先,使用箭头函数,其次,使用`this.contact = data;

activate(id) { 
    this.id = id; 
    return dpd.contacts.get(id).then(data => { 
    console.log(data); 
    this.contact = data; 
    }); 
} 

你用一个箭头的功能,因为它使用JavaScript的“this”的问题,在此指的是功能的词汇范围,而不是目前在你的对象的交易。使用箭头功能可确保this以外的箭头功能与this里面的箭头功能相同。

您需要使用this.contact,因为contact是该类的实例属性。

+1

今天所有堆栈溢出的最佳答案 –

+0

@MatthewJamesDavis我同意,箭头函数的伎俩。 –

+0

@AshleyGrant,也许你可以添加一两句话来说明为什么箭头函数修复了这个问题?我要去读这篇文章,但是我确信会帮助其他人。 –

2

问题是contact = data;将更新本地contact变量的值,但不会更改this.contact的值。 您需要改为更新contact联系人属性。问题在于你不能访问函数内核中的this

有不同的方法来解决这个问题。

1您可以保存激活的情况下(this)为变量的activate关闭,这样就可以访问它的then内线核心。

activate(id) { 
    this.id = id; 
    let that = this; 
    return dpd.contacts.get(id).then(function(data) { 
     console.log(data); 
     that.contact = data; 
    }); 
    } 

2 - 可以绑定功能this这样你就可以访问它。

activate(id) { 
    this.id = id; 
    return dpd.contacts.get(id).then(function(data) { 
     console.log(data); 
     this.contact = data; 
    }.bind(this)); 
    } 

3-(建议使用ES6),你可以用一个箭头功能(箭头功能保存上下文)

activate(id) { 
    this.id = id; 
    return dpd.contacts.get(id).then((data) => { 
     console.log(data); 
     this.contact = data; 
    }); 
    } 
+0

我已经尝试#1没有运气。去试试#2,看看它是如何工作的。 #3作品。 –

+0

#1和#2也可以工作。我的错误是使用'let contact = this.contact'。显然这不会工作,因为'let that = this' does not work。奇怪,但我会接受。 –

+0

这并不奇怪。如果你做'contact = something',你正在为'contact' **变量赋值一个新值。您不修改分配给它的以前的值。你要做的是改变'this'对象的'contact'属性。这个属性与'contact'变量无关(除了你将它的值初始化为'this.contact'指向的值)。改变对象'obj'属性'prop'所指的值的唯一方法就是写一些类似于'obj.prop = something'的东西。 –