在我的js文件中添加了几行代码之后,却出现了错误Error: A 'pure' computed must not be called recursively
,但我不知道为什么。这是文件的开头:
import knockout from 'knockout';
import BaseViewModel from '../checkout/base';
import Is from '../is';
import jQuery from 'jquery';
const AddressViewModel = ((ko, is, $) => {
const CountryCode = {
CANADA: 'CA',
USA: 'US'
};
const CITY_ENTER_OTHER = 'Enter Other City';
class AddressViewModel extends BaseViewModel {
constructor() {
super();
this.addressId = ko.observable();
this.locationDescription = ko.observable();
this.addressLine1 = ko.observable();
this.addressLine2 = ko.observable();
this.postalCode = ko.observable();
this.cityEntered = ko.observable();
this.citySelected = ko.observable();
this.cityOptions = ko.observableArray();
this.countryCode = ko.observable();
this.state = ko.observable();
this.province = ko.observable();
this.addressTypeCode = ko.observable();
this.alreadyChecked = ko.observable(false);
this.stateCheck = ko.observable(false);
this.initialValueUsed = ko.observable(false);
this._initComputedValues();
this._initSubscribers();
}
_initComputedValues() {
// this next code is what I added that is causing the error
this.addressLine1 = ko.pureComputed({
read: this._readAddressLine1,
write: this._writeAddressLine1,
owner: this
});
this.postalCode = ko.pureComputed({
read: this._readPostalCode,
write: this._writePostalCode,
owner: this
});
我最近添加了以this.
开头的最后两个块。稍后,我还在文件中添加了读/写定义。在_initComputedValues
函数之外,我还添加了以下内容:
_readAddressLine1() {
let address = this.addressLine1();
let returnValue = this.replaceSpecialCharacters(address);
return returnValue;
}
_writeAddressLine1(address) {
this.addressLine1(address);
}
_readPostalCode() {
let postalCode = this.postalCode();
let returnValue = this.replaceSpecialCharacters(postalCode);
return returnValue;
}
_writePostalCode(postalCode) {
this.postalCode(postalCode);
}
现在在添加该代码之后,就是我开始遇到该错误的时候。
最后,我的replaceSpecialCharacters
函数来自另一个名为convert-special-characters.js的文件:
import BaseViewModel from '../checkout/base';
const CharacterViewModel = (() => {
class CharacterViewModel extends BaseViewModel {
constructor() {
super();
this._initComputedValues();
}
_initComputedValues() {
this.createConversionMap = this._createConversionMap.bind(this);
this.replaceSpecialCharacters = this._replaceSpecialCharacters.bind(this);
}
_createConversionMap() { // from https://stackoverflow.com/a/49139933/571723
let map = {};
// Open-quotes: http://www.fileformat.info/info/unicode/category/Pi/list.htm
map[0x2018] = '\'';
map[0x201B] = '\'';
map[0x201C] = '"';
map[0x201F] = '"';
// Close-quotes: http://www.fileformat.info/info/unicode/category/Pf/list.htm
map[0x2019] = '\'';
map[0x201D] = '\"';
// Primes: http://www.fileformat.info/info/unicode/category/Po/list.htm
map[0x2032] = '\'';
map[0x2033] = '"';
map[0x2035] = '\'';
map[0x2036] = '"';
map[0x2014] = '-'; // iOS 11 also replaces dashes with em-dash
map[0x2013] = '-'; // and "--" with en-dash
return map;
}
_replaceSpecialCharacters(value) {
let conversionMap = this.createConversionMap;
let returnValue = '';
for (let i = 0; i < value.length; i++) {
let replacement = conversionMap[value.charAt(i)];
if (replacement) {
returnValue = value.replace(value.charAt(i), replacement);
}
}
return returnValue;
}
}
return CharacterViewModel;
})();
export default CharacterViewModel;
答案 0 :(得分:2)
您已在顶部将addressLine1声明为可观察对象,然后在以后进行计算时再次声明了它。我猜这些应该是两个不同的属性?计算版本试图返回可观察值的值,这就是正在发生的递归。您不能将计算用途本身用作背景字段。
this.addressLine1 = ko.observable();
...
this.addressLine1 = ko.pureComputed({
read: this._readAddressLine1,
write: this._writeAddressLine1,
owner: this
});
...
_readAddressLine1() {
let address = this.addressLine1();
let returnValue = this.replaceSpecialCharacters(address);
return returnValue;
}
计算只是具有自动触发器的函数;它永远不会存储值。让它在其定义内使用自己的值就是要它求解x,其中x是x的某个函数。如果它没有给您带来有用的编译错误,则会出现堆栈溢出。您可能应该将可观察对象重命名为_addressLine1
之类,因此代码为:
this._addressLine1 = ko.observable();
this.addressLine1 = ko.pureComputed({
read: this._readAddressLine1,
write: this._writeAddressLine1,
owner: this
});
...
_readAddressLine1() {
let address = this._addressLine1();
let returnValue = this.replaceSpecialCharacters(address);
return returnValue;
}
_writeAddressLine1(address) {
this._addressLine1(address);
}