请参阅以下使用ExtJS配置功能的HTML + JS + ExtJS代码。
<!DOCTYPE html>
<html>
<head>
<title>Ext-JS config missing setAge() problem</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/extjs/6.0.0/ext-all.js"></script>
<script>
Ext.define('Student', {
config: {
name: 'anonymous',
age: 0
},
constructor: function (config) {
this.initConfig(config);
},
putName: function (name) {
this.config.name = name
}
});
var studentObj = Ext.create('Student', {name: 'Alice', age: 12})
console.log('before putName: methods: ' + studentObj.getName() + ', ' + studentObj.getAge());
console.log('before putName: internal: ' + studentObj._name + ', ' + studentObj._age);
console.log('before putName: config: ' + studentObj.config.name + ', ' + studentObj.config.age);
studentObj.putName('Bob');
console.log('after putName: methods: ' + studentObj.getName() + ', ' + studentObj.getAge());
console.log('after putName: internal: ' + studentObj._name + ', ' + studentObj._age);
console.log('after putName: config: ' + studentObj.config.name + ', ' + studentObj.config.age);
</script>
</head>
<body>
</body>
</html>
这提供了预期的输出。
"before putName: methods: Alice, 12"
"before putName: internal: Alice, 12"
"before putName: config: Alice, 12"
"after putName: methods: Alice, 12"
"after putName: internal: Alice, 12"
"after putName: config: Bob, 12"
但如果我在上面的代码中将putName
替换为setName
,那么我会得到
以下输出。
"before setName: methods: undefined, 12"
"before setName: internal: undefined, 12"
"before setName: config: Alice, 12"
"after setName: methods: undefined, 12"
"after setName: internal: undefined, 12"
"after setName: config: Bob, 12"
在这种情况下,为什么内部_name
变量设置为undefined
?为什么getName()
来电回复undefined
?
我知道我不应该定义我的setName()
方法
而是定义applyName()
方法。但我想了解
这是怎么回事。
在我看来,当我定义setName()
方法时,它会变得混乱
关于如何在ExtJS中维护配置的内部变量。
您能否准确描述在这种情况下内部_name
变量未定义的原因?
答案 0 :(得分:1)
为config
成员自动生成的getter和setter实现实际上是从父类继承的 - 如果覆盖未在API中标记为模板函数的方法,则需要调用“超级“方法,如果您希望保留原始行为 - 您可以使用callParent
来实现此目的,例如:
Ext.define('MyClass', {
config: {
foo: 'bar'
},
constructor: function(config){
this.initConfig(config);
},
setFoo: function(value){
// custom setter code
this.callParent(arguments);
}
});
请注意,如果您选择手动操作各个参数,callParent
总是需要一个数组 - 否则您可以简单地按原样传递函数arguments
。也就是说,通常你不需要覆盖setter,文档说明出于优化的原因,你不应该调用任何会触发布局的代码。
另一种选择是挂钩update
模板方法。与getter和setter一样,每个config
成员也会获得一个“update”前缀方法,默认情况下该方法指向Ext.emptyFn
。在设置了值之后调用此方法,并且不会干扰超类,例如
Ext.define('MyClass', {
config: {
foo: 'bar'
},
// ...
updateFoo: function(value){
// do something
}
});
答案 1 :(得分:0)
getter和setter方法的默认实现使用属性def palindrome(s):
return s == s[::-1]
来存储值,这就是它无法工作的原因。
如果您要覆盖_<name>
,则需要设置setName
this._name
演示:Fiddle
但是如果一个更合适的方法,如果你只是想在设置属性值时做一些自定义操作,那就是使用像Ext.define('Student', {
config: {
name: 'anonymous',
age: 0
},
constructor: function(config) {
this.initConfig(config);
},
setName: function(name) {
this._name = name
}
});
这样的方法
apply<property>
演示:Fiddle