2015-07-13 238 views
2

我在使用ES6時遇到'this'範圍問題。'this'scope with ES6 and Knockout

Here's一個鏈接到我original and transpiled code與BabelJS。

當調用一個函數從數組中刪除一個項時,'this'的作用域是未定義的。

我怎樣才能使這個沒有重新定義這(let self = this)?

"use strict"; 
 

 
var _createClass = (function() { 
 
    function defineProperties(target, props) { 
 
    for (var i = 0; i < props.length; i++) { 
 
     var descriptor = props[i]; 
 
     descriptor.enumerable = descriptor.enumerable || false; 
 
     descriptor.configurable = true; 
 
     if ("value" in descriptor) descriptor.writable = true; 
 
     Object.defineProperty(target, descriptor.key, descriptor); 
 
    } 
 
    } 
 
    return function(Constructor, protoProps, staticProps) { 
 
    if (protoProps) defineProperties(Constructor.prototype, protoProps); 
 
    if (staticProps) defineProperties(Constructor, staticProps); 
 
    return Constructor; 
 
    }; 
 
})(); 
 

 
function _classCallCheck(instance, Constructor) { 
 
    if (!(instance instanceof Constructor)) { 
 
    throw new TypeError("Cannot call a class as a function"); 
 
    } 
 
} 
 

 
var Point = (function() { 
 
    function Point() { 
 
    var _this = this; 
 

 
    _classCallCheck(this, Point); 
 

 
    this.myArray = ko.observableArray([1, 2, 3, 4]); 
 
    this.removeFromArrayWithArrowFunction = function(value) { 
 
     _this.myArray.remove(value); 
 
    }; 
 
    } 
 

 
    _createClass(Point, [{ 
 
    key: "removeFromArray", 
 
    value: function removeFromArray(value) { 
 
     this.myArray.remove(value); 
 
    } 
 
    }]); 
 

 
    return Point; 
 
})(); 
 

 
ko.applyBindings(new Point());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<span data-bind="text: ko.toJSON(myArray)"></span> 
 
<h2>Issues with this scoping when using a regular Function</h2> 
 
<ul data-bind="foreach: myArray"> 
 
    <li> 
 
    <a href="#" data-bind="text: $data, click: $parent.removeFromArray"></a> 
 

 
    </li> 
 
</ul> 
 

 
<h2>Works as expected using an arrow function</h2> 
 
<ul data-bind="foreach: myArray"> 
 
    <li> 
 
    <a href="#" data-bind="text: $data, click: $parent.removeFromArrayWithArrowFunction"></a> 
 

 
    </li> 
 
</ul>

+1

這是不是一個真正的問題ES6,要綁定的'click'事件對象的方法。你正在失去'this'的背景。您需要將該方法綁定到父對象。 –

+0

謝謝@JeffMercado。有關如何實現它的任何建議? –

+2

sroes提供了一個ES6解決方案。否則,使用[這裏]概述的任何方法(http://stackoverflow.com/questions/10737494/context-of-this-when-triggering-method-on-root-from-child)。 –

回答

1

如果您直接在綁定使用視圖模型的功能,你失去的this上下文像傑夫·梅爾卡多解釋。 Arrow functions capture the this value of the enclosing context,所以如果你使用箭頭函數表示法,你不必擔心var self = this

所以改變如下:

removeFromArray(value) { 
    this.myArray.remove(value); 
} 

分爲:

removeFromArray = (value) => { 
    this.myArray.remove(value); 
} 

,它應該工作的罰款。

See babel

+5

請向您的解決方案添加說明,尤其是您正在使用ES7提案。這不是ES6。另外,你的解決方案基本上是OP用'this.removeFromArrayWithArrowFunction = value => {this.myArray.remove(value);}'做的。 –

+1

你是對的@FelixKling。我在本地嘗試過,因爲我沒有使用實驗性Babel功能,所以無法正常工作。任何其他選項? –

+1

正是OP已經做了什麼,在構造函數中設置函數。 –