Javascript 在Aurelia中重新计算绑定后触发回调

Javascript 在Aurelia中重新计算绑定后触发回调,javascript,aurelia,Javascript,Aurelia,我正在构建一个拖放工作区,类似于您在制作实体模型时找到的工作区。我有一个工作空间自定义元素,它有一个更大的嵌套元素,可以缩放和平移。因此,我需要仔细跟踪工作区和所有包含元素的大小和位置数据 在我的自定义元素的附加事件中,我通过编程将工作区的高度和宽度设置为JavaScript对象,该对象绑定到视图中的css: workspaceCustomElement.js export class WorkspaceCustomElement { constructor(element) {

我正在构建一个拖放工作区,类似于您在制作实体模型时找到的工作区。我有一个工作空间自定义元素,它有一个更大的嵌套元素,可以缩放和平移。因此,我需要仔细跟踪工作区和所有包含元素的大小和位置数据

在我的自定义元素的附加事件中,我通过编程将工作区的高度和宽度设置为JavaScript对象,该对象绑定到视图中的css:

workspaceCustomElement.js

export class WorkspaceCustomElement {

    constructor(element) {
        this.element = element;
    }

    attached() {
        this.workspace.size = {
            height: this.element.height * 5,
            width: this.element.width * 5
        }
    }
}
export class WorkspaceCustomElement {

    constructor(element, queue) {
        this.element = element;
        this.queue = queue;
    }

    attached() {
        this.workspace.size = {
            height: this.element.height * 5,
            width: this.element.width * 5
        }
        this.queue.queueMicroTask(() => {
            let components = this.element.querySelectorAll('.component');
            Array.prototype.forEach.call(components, (component) => {
                let model = component.model;
                model.position = { 
                    x: component.clientLeft,
                    y: component.clientTop
                };
            }
        });
    }
}
workspaceCustomElement.html

<div css="height: ${workspace.height}px; width: ${workspace.width}px; 
    left: ${(element.clientWidth - workspace.width)/2}px; 
    top: ${(element.clientHeight - workspace.height)/2}px;"></div>

是否有更好、更可靠的方法在下一次绑定更新后将指令排队?

最佳做法是将任务添加到
任务队列中。在引擎罩下,绑定引擎使用
TaskQueue
本身,因此添加新任务将在绑定更新之后对其进行排队

workspaceCustomElement.js

export class WorkspaceCustomElement {

    constructor(element) {
        this.element = element;
    }

    attached() {
        this.workspace.size = {
            height: this.element.height * 5,
            width: this.element.width * 5
        }
    }
}
export class WorkspaceCustomElement {

    constructor(element, queue) {
        this.element = element;
        this.queue = queue;
    }

    attached() {
        this.workspace.size = {
            height: this.element.height * 5,
            width: this.element.width * 5
        }
        this.queue.queueMicroTask(() => {
            let components = this.element.querySelectorAll('.component');
            Array.prototype.forEach.call(components, (component) => {
                let model = component.model;
                model.position = { 
                    x: component.clientLeft,
                    y: component.clientTop
                };
            }
        });
    }
}

有关更多信息,请参见此处:

您可以创建一个绑定行为,该行为在绑定更新目标(DOM元素/自定义元素/自定义属性)时调用您选择的回调

下面是一个例子:

target updated.js

export class WorkspaceCustomElement {

    constructor(element) {
        this.element = element;
    }

    attached() {
        this.workspace.size = {
            height: this.element.height * 5,
            width: this.element.width * 5
        }
    }
}
export class WorkspaceCustomElement {

    constructor(element, queue) {
        this.element = element;
        this.queue = queue;
    }

    attached() {
        this.workspace.size = {
            height: this.element.height * 5,
            width: this.element.width * 5
        }
        this.queue.queueMicroTask(() => {
            let components = this.element.querySelectorAll('.component');
            Array.prototype.forEach.call(components, (component) => {
                let model = component.model;
                model.position = { 
                    x: component.clientLeft,
                    y: component.clientTop
                };
            }
        });
    }
}
导出类TargetUpdatedBindingBehavior{
绑定(绑定、源、回调){
//重写绑定的updateTarget方法。添加要调用的逻辑
//回调作为参数传递给绑定行为。
binding.standardUpdateTarget=binding.updateTarget;
binding.targetUpdatedCallback=回调;
binding.updateTarget=函数(值){
这个.standardUpdateTarget(值);
this.targetUpdatedCallback(this.target,this.targetProperty,value);
};
}
解除绑定(绑定,源){
//将绑定还原为其原始状态。
binding.updateTarget=binding.standardUpdateTarget;
binding.standardUpdateTarget=null;
binding.targetUpdatedCallback=null;
}
}


@MathewJamesDavis的答案完全正确,我只是提供了第二个选项。

使用Aurelia的
任务队列如何?哇,很酷,在我的例子中,这不是一个很棘手的实现,因为我实际上是在一个元素数组上触发一个事件吗?这很好,我在很多地方使用了这种技术。基本上,在任何地方,当我不想直接绑定时,只要有变化就触发。