Aurelia:总是在视图中调用方法(升级后出现问题)

Aurelia: always call method in the view (problems after upgrade)

本文关键字:问题 方法 视图 调用 Aurelia      更新时间:2023-09-26

我们已经升级了Aurelia(特别是aurelia-framework1.0.6aurelia-bindong1.0.3),现在我们面临一些绑定问题。

有一个带有计算类的元素列表,我们在包含该列表的自定义元素中有一个方法:

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类仍然没有应用。

所以,问题是:

如何强制Aurelia调用视图中属性中的方法

P.S

我知道这可能会导致一些性能问题。

小提示:

我不能简单地向列表元素添加selected属性,因为我不想以某种方式修改自定义元素中的数据,而且我基本上希望我的代码能够正常工作,而不会进行太多更改。

UPD

我最终得到了Fabio Luz的这个很棒的解决方案,并进行了以下小编辑:

UPD以下是Fabio Luz的精彩解决方案。

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));

但我最终得到了这个(定义了一个额外的数组)。

您必须使用属性而不是函数。像这样:

//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>

编辑

我知道这可能有些过头了,但这是迄今为止我找到的最好的解决方案:

为您的对象创建一个类:

export class MyClass {
   constructor(id, value) {
      this.id = id;
      this.value = value;
   }
   get getClass() {
      //do your magic here
      return 'your css classes';
   }
}

使用上面的类创建数组的对象:

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>

希望它能有所帮助!

看起来很悲伤。

我不理解你在html中计算类的观点。试试那个代码,它会对你有所帮助。

computedClass(item){
  return `
     ${this.getClass(item)}
     ${~selected.indexOf(item) ? 'disabled-option': ''}
     ${item === this.currentTag ? 'selected-option' : ''}
  `;
}

如果状态为/,您的代码不起作用会导致您首先错过其他选项

更新:要切换属性状态,请尝试selected.bind="true/false"

祝你好运,Egor

Fabio提供了一个很好的解决方案,但它引起了问题(双向绑定到自定义元素的数据(选择的结果)与输入的类型不同,等等)。这肯定是可以修复的,但这将花费大量的时间,并导致重写测试等。或者,是的,我们可以将原始对象作为一些属性等等。。。

无论如何:

还有另一种解决方案,虽然不那么优雅,但实现起来要快得多。

  1. 让我们声明一个额外的数组

    @bindable shownProperties = [];
    
  2. 注入ObserverLocator

  3. 观察所选阵列

    this.obsLoc.getArrayObserver(this.selected)
        .subscribe(() => this.selectedArrayChanged);
    
  4. 更新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])
            }
        }
    } 
    
  5. 最后,在观点上:

    class="... ${shownProperties[$index].selected ? 'disabled-option' : '')} ..."
    

所以,这个故事的寓意是:

不要像我那样在视图中使用方法:)