1

我现在正在学习 Aurelia 几个星期,我似乎遇到了自定义属性的数据绑定问题。

我创建了以下square自定义属性(基于Aurelia 网站上“模板:自定义属性”指南中的示例):

方.ts:

import { bindable, autoinject } from "aurelia-framework";

@autoinject
export class SquareCustomAttribute {
  @bindable sideLength = "100px";
  @bindable color = "red";

  constructor(private element: Element) {
    this.sideLengthChanged(this.sideLength);
    this.colorChanged(this.color);
  }

  sideLengthChanged(newValue: string) {
    if (this.element instanceof HTMLElement) {
      this.element.style.width = this.element.style.height = newValue;
    }
  }

  colorChanged(newValue: string) {
    if (this.element instanceof HTMLElement) {
      this.element.style.backgroundColor = newValue;
    }
  }
}

我希望这个自定义属性可以在没有显式绑定的情况下使用,在这种情况下它应该使用默认值,就像在这个消费视图中一样:

应用程序.html:

<template>
  <require from="./square"></require>
  <div square></div>
</template>

上面的代码工作正常。div它将100px 边和红色背景渲染为正方形。

当我将color属性设置SquareCustomAttribute为主要属性(使用@bindable的配置对象参数)时出现问题,如下所示:

更新 square.ts:

import { bindable, autoinject } from "aurelia-framework";

@autoinject
export class SquareCustomAttribute {
  @bindable sideLength = "100px";
  @bindable({ primaryProperty: true }) color = "red";

  constructor(private element: Element) {
    this.sideLengthChanged(this.sideLength);
    this.colorChanged(this.color);
  }

  sideLengthChanged(newValue: string) {
    if (this.element instanceof HTMLElement) {
      this.element.style.width = this.element.style.height = newValue;
    }
  }

  colorChanged(newValue: string) {
    if (this.element instanceof HTMLElement) {
      this.element.style.backgroundColor = newValue;
    }
  }
}

出于某种原因,设置color为自定义属性的主要属性,colorChanged回调现在被调用两次:首先由构造函数使用默认值,然后再次从生命周期初始化的某个地方使用空值。

如何避免第二次调用回调,以便当我没有在消费视图的 HTML 标记中colorChanged明确提供属性的绑定/值时,我的自定义属性的主要属性的默认值不会被清除?square

4

1 回答 1

3

您将不得不以另一种方式解决这个问题:

import { bindable, autoinject } from "aurelia-framework";

@autoinject
export class SquareCustomAttribute {
  @bindable sideLength;
  @bindable({ primaryProperty: true }) color;

  constructor(private element: Element) {
  }

  sideLengthChanged(newValue: string) {
    if (this.element instanceof HTMLElement) {
      this.element.style.width = this.element.style.height = newValue;
    }
  }
  
  bind(){
    this.sideLengthChanged(this.sideLength ? this.sideLength : "100px");
    this.colorChanged(this.color ? this.color : "red");
  }

  colorChanged(newValue: string) {
    if (this.element instanceof HTMLElement) {
      this.element.style.backgroundColor = newValue;
    }
  }
}

当您声明时{ primaryProperty: true },您基本上是在告诉框架为您的自定义属性的值创建一个绑定,无论是否填充,框架都会将其映射到您的颜色属性。所以当你声明时<div square></div>,生命周期中的颜色属性bind()将是一个空字符串。由于bind()只调用一次,它是声明默认值的最佳位置,如果它们一开始是空的。

此处示例:https ://gist.dumber.app/?gist=b0244ac4078e2a0664b7be0fbcc0b22b

于 2020-07-01T06:59:29.760 回答