Aurelia:总是在视图中调用方法(升级后出现问题)
Aurelia: always call method in the view (problems after upgrade)
我们已经升级了 Aurelia(特别是 aurelia-framework
到 1.0.6
,aurelia-bindong
到 1.0.3
),现在我们面临一些绑定问题。
有一个包含计算 classes 的元素列表,我们有一个方法 int 包含该列表的自定义元素:
getClass(t) {
return '...' +
(this.selected.indexOf(t) !== -1
? 'disabled-option' :
: ''
) + (t === this.currentTag
? 'selected-option'
: ''
);
}
对于列表元素class.one-way="$parent.getClass(t)"
,一切正常。
升级后它就停止工作了,所以每当 selected
(顺便说一句,它是可绑定的)或 currentTag
属性被修改时,getClass
方法就不会被调用。
我通过将此逻辑移动到视图来部分解决了这个问题:
class="${$parent.getClass(t) + (selected.indexOf(t) !== -1 ? 'disabled-option' : '') (t === $parent.currentTag ? 'selected-option' : '')}"
我知道这看起来,好吧...很糟糕,但这让 t === $parent.currentTag
工作了,但是 disabled-option
class 仍然没有应用。
所以,问题是:
如何强制 Aurelia 在视图中调用属性中的方法?
P.S.
我知道这可能会导致一些性能问题。
小记:
我不能简单地向列表元素添加一个 selected
属性,因为我不想以某种方式修改自定义元素的数据,我基本上希望我的代码能够正常工作而不会做太多变化。
UPD
我通过以下小修改得到了 :
UPD 这里有一种解释.
export class SelectorObjectClass {
constructor(el, tagger){
Object.assign(this, el);
this.tagger = tagger;
}
get cssClass(){
//magic here
}
}
和
this.shown = this.shown(e => new SelectorObjectClass(e, this));
但我最终得到了 。
看起来很悲伤。
我想不明白你在 html 中计算 class 的意义。试试那个代码,它应该对你有帮助。
computedClass(item){
return `
${this.getClass(item)}
${~selected.indexOf(item) ? 'disabled-option': ''}
${item === this.currentTag ? 'selected-option' : ''}
`;
}
你的代码不起作用,因为你一开始就错过了 else 选项 if state :/
更新:
要切换属性状态,请尝试 selected.bind="true/false"
祝你好运,
叶戈尔
您必须使用 属性 而不是函数。像这样:
//pay attention at the "get" before function name
get getClass() {
//do your magic here
return 'a b c d e';
}
HTML:
<div class.bind="getClass"></div>
编辑
我知道这可能有点矫枉过正,但这是我迄今为止找到的最好的解决方案:
为您的对象创建 class:
export class MyClass {
constructor(id, value) {
this.id = id;
this.value = value;
}
get getClass() {
//do your magic here
return 'your css classes';
}
}
使用上面的class创建数组的对象:
let shown = [];
shown[1] = new MyClass('someId', 'someValue');
shown[2] = new MyClass('someId', 'someValue');
现在,您将可以使用 getClass
属性:
<div repeat.for="t of shown" class.bind="t.getClass">...</div>
希望对您有所帮助!
提供了一个很好的解决方案,但它引起了问题(two-way 绑定到自定义元素(选择的结果)的数据与输入等)。这绝对可以修复,但它会花费 大量 时间并导致重写测试等。或者,是的,我们可以将原始对象作为一些 属性 blah-blah-blah...
无论如何:
还有另一种解决方案,不太优雅但实施起来要快得多。
让我们声明一个额外的数组
@bindable shownProperties = [];
注入ObserverLocator
观察选中的数组
this.obsLoc.getArrayObserver(this.selected)
.subscribe(() => this.selectedArrayChanged);
更新shownProperties
isSelected(t) {
return this.selected.indexOf(t) !== -1;
}
selectedArrayChanged(){
for(var i = 0; i < this.shown.length; i++){
this.shownProperties[i] = {
selected: this.isSelected(this.shown[i])
}
}
}
最后,在视图中:
class="... ${shownProperties[$index].selected ? 'disabled-option' : '')} ..."
所以,故事的寓意:
不要像我一样在视图中使用方法:)
我们已经升级了 Aurelia(特别是 aurelia-framework
到 1.0.6
,aurelia-bindong
到 1.0.3
),现在我们面临一些绑定问题。
有一个包含计算 classes 的元素列表,我们有一个方法 int 包含该列表的自定义元素:
getClass(t) {
return '...' +
(this.selected.indexOf(t) !== -1
? 'disabled-option' :
: ''
) + (t === this.currentTag
? 'selected-option'
: ''
);
}
对于列表元素class.one-way="$parent.getClass(t)"
,一切正常。
升级后它就停止工作了,所以每当 selected
(顺便说一句,它是可绑定的)或 currentTag
属性被修改时,getClass
方法就不会被调用。
我通过将此逻辑移动到视图来部分解决了这个问题:
class="${$parent.getClass(t) + (selected.indexOf(t) !== -1 ? 'disabled-option' : '') (t === $parent.currentTag ? 'selected-option' : '')}"
我知道这看起来,好吧...很糟糕,但这让 t === $parent.currentTag
工作了,但是 disabled-option
class 仍然没有应用。
所以,问题是:
如何强制 Aurelia 在视图中调用属性中的方法?
P.S.
我知道这可能会导致一些性能问题。
小记:
我不能简单地向列表元素添加一个 selected
属性,因为我不想以某种方式修改自定义元素的数据,我基本上希望我的代码能够正常工作而不会做太多变化。
UPD
我通过以下小修改得到了
UPD 这里有一种解释
export class SelectorObjectClass {
constructor(el, tagger){
Object.assign(this, el);
this.tagger = tagger;
}
get cssClass(){
//magic here
}
}
和
this.shown = this.shown(e => new SelectorObjectClass(e, this));
但我最终得到了
看起来很悲伤。
我想不明白你在 html 中计算 class 的意义。试试那个代码,它应该对你有帮助。
computedClass(item){
return `
${this.getClass(item)}
${~selected.indexOf(item) ? 'disabled-option': ''}
${item === this.currentTag ? 'selected-option' : ''}
`;
}
你的代码不起作用,因为你一开始就错过了 else 选项 if state :/
更新:
要切换属性状态,请尝试 selected.bind="true/false"
祝你好运, 叶戈尔
您必须使用 属性 而不是函数。像这样:
//pay attention at the "get" before function name
get getClass() {
//do your magic here
return 'a b c d e';
}
HTML:
<div class.bind="getClass"></div>
编辑
我知道这可能有点矫枉过正,但这是我迄今为止找到的最好的解决方案:
为您的对象创建 class:
export class MyClass {
constructor(id, value) {
this.id = id;
this.value = value;
}
get getClass() {
//do your magic here
return 'your css classes';
}
}
使用上面的class创建数组的对象:
let shown = [];
shown[1] = new MyClass('someId', 'someValue');
shown[2] = new MyClass('someId', 'someValue');
现在,您将可以使用 getClass
属性:
<div repeat.for="t of shown" class.bind="t.getClass">...</div>
希望对您有所帮助!
无论如何:
还有另一种解决方案,不太优雅但实施起来要快得多。
让我们声明一个额外的数组
@bindable shownProperties = [];
注入
ObserverLocator
观察选中的数组
this.obsLoc.getArrayObserver(this.selected) .subscribe(() => this.selectedArrayChanged);
更新
shownProperties
isSelected(t) { return this.selected.indexOf(t) !== -1; } selectedArrayChanged(){ for(var i = 0; i < this.shown.length; i++){ this.shownProperties[i] = { selected: this.isSelected(this.shown[i]) } } }
最后,在视图中:
class="... ${shownProperties[$index].selected ? 'disabled-option' : '')} ..."
所以,故事的寓意:
不要像我一样在视图中使用方法:)