2016-07-14 9 views
1

モックアップの作成に似たドラッグアンドドロップ作業領域を構築しています。私は拡大してパンすることができるより大きな、入れ子にされた要素を持つワークスペースカスタム要素を持っています。したがって、ワークスペースとすべての含まれている要素のサイズと位置データを注意深く追跡する必要があります。バインディングがAureliaで再評価された後のコールバックのトリガー

私のカスタム要素の私の添付イベントでは、私はプログラム的にビューにCSSにバインドされているJavaScriptオブジェクトとしてワークスペースの高さと幅を設定します。

workspaceCustomElement.js

は、
export class WorkspaceCustomElement { 

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

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

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> 

今、私の子要素の位置を取得しようとすると問題に遭遇しています。私もそれらにコールバックを添付していますが、の前にはのコールバックが添付されています。したがって、CSSバインディングは評価されておらず、サイズと位置が間違っています。

は私がattached()が評価されたとのバインディングが更新された後にコールバックを追加する必要があります。私はsetTimeoutハックを使ってこれを達成できますが、これはいつもうまくいくという自信がありません。

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

    setTimeout(() => { 
     let components = this.element.querySelectorAll('.component'); 
     Array.prototype.forEach.call(components, (component) => { 
      let model = component.model; 
      model.position = { 
       x: component.clientLeft, 
       y: component.clientTop 
      }; 
     } 
    }, 0) 
} 

次のバインド更新後に命令をキューに入れる方が、より確実で信頼性の高い方法がありますか?

+2

Aureliaの 'TaskQueue'はどうですか? http://stackoverflow.com/questions/36049391/is-there-a-callback-or-promise-for-aurelia-show-bind –

答えて

4

ベストプラクティスは、TaskQueueにタスクを追加することです。フードの下では、バインディングエンジンはTaskQueueを使用しているので、新しいタスクを追加すると、バインディングアップデートの後ろにキューが置かれます。

workspaceCustomElement.js

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

は、詳細についてはこちらをご覧ください:TaskQueue API

3

あなたはいつでもバインディングアップデート対象あなたが選んだのコールバックを呼び出し結合挙動を作成することができます(DOM要素/カスタム要素/カスタム属性)。ここで

は例です:https://gist.run?id=28c0fedb21b5d8100913d3bc5500499f

目標updated.js

export class TargetUpdatedBindingBehavior { 
    bind(binding, source, callback) { 
    // override the binding's updateTarget method. add logic to invoke 
    // the callback passed as a parameter to the binding behavior. 
    binding.standardUpdateTarget = binding.updateTarget; 
    binding.targetUpdatedCallback = callback; 
    binding.updateTarget = function(value) { 
     this.standardUpdateTarget(value); 
     this.targetUpdatedCallback(this.target, this.targetProperty, value); 
    }; 
    } 

    unbind(binding, source) { 
    // revert the binding to it's original state. 
    binding.updateTarget = binding.standardUpdateTarget; 
    binding.standardUpdateTarget = null; 
    binding.targetUpdatedCallback = null; 
    } 
} 

http://aurelia.io/hub.html#/doc/article/aurelia/binding/latest/binding-binding-behaviors

MathewJamesDavisの答え@私はちょうど目のオプションとしてこれを提供しています、完全に有効です。

+0

私の場合、これは難しい実装ではないでしょうか、実際には要素の配列でイベントをトリガしていますか? –

+0

これは面白いです、私はこのテクニックを多くの場所で使っています。基本的にどこでも、私は直接バインディングをしたくないときに、何かが変わったときに起動されます。 – balazska

関連する問題