2017-05-15 13 views
0

私は現在、IBMのループバックを使ってnode.jsにREST APIを書いています。私はオブザーバーの順序が関係している問題にぶつかりつつあり、間違った順序で呼び出されます。ループバックオブザーバの順番を定義する

私のチケットモデルは内部ステータスフィールドを持っています。このステータスは、UUIDとしてデータベースに格納されます。大きな「メタデータ」ファイルのどこかに、各ステータスの人名も定義されています。 外部ステータスフィールドについても同様です。ここで

Ticket.jsonの関連する部分です:

{ 
    "name": "Ticket", 
    "properties": { 
    "internalStatusId": { 
     "type": "String" 
    }, 
    "externalStatusId": { 
     "type": "String" 
    } 
    } 
} 

私は正しいUUIDに、このようなUUIDフィールドの人間の名前を変換することができ、一般的なミックスインを書かれています。このミックスインは、クライアントがUUIDフィールドをその名前で(別の名前のフィールドを介して)設定できるようにするために使用されます。ここで

はミックスインの簡易版である:

// This observer is actually a simplification of the actual observer, 
// which is more generic. It handles "name to id" mapping for any number 
// of fields you can configure in the <model>.json file. 
Model.observe('before save', function (ctx, next) { 
    let data = ctx.isNewInstance ? ctx.instance : ctx.data; 
    if (data.internalStatusName) { 
    data.internalStatusId = internalStatusNameToIdMap[data.internalStatusName]; 
    delete data.internalStatusName; 
    } 
    next(); 
}); 

は、あなたが体として{ "internalStatusName": "Closed" }/Tickets/1PUTリクエストを送信する場合、このコードが正しいUUIDにそれを変換しますので、internalStatusIdフィールドであることを置きます引数からinternalStatusNameフィールドを削除します。

システムにビジネスルールがあります。内部ステータスがClosedに設定されている場合は、外部ステータスもClosedに設定する必要があります。それはチケットモデルのための一般的なだけでは関係がないですので、そのためのコードは、Ticket.js次の場所にあります。

// This observer is located in Ticket.json. 
// It makes sure that, when a ticket's internal status is set to Closed, 
// the external status is also set to Closed. 
Ticket.observe('before save', function (ctx, next) { 
    let data = ctx.isNewInstance ? ctx.instance : ctx.data; 
    if (data.internalStatusId === INTERNAL_STATUS_CLOSED_UUID) { 
    data.externalStatusId = EXTERNAL_STATUS_CLOSED_UUID; 
    } 
    next(); 
}); 

私はに実行している問題は、これら2人の観察者が一緒にうまく機能しないということです、それらは間違った順序で呼び出されるからです。

私は{ "internalStatusName": "Closed" }を送信する場合:

  • まずTicket.jsからのオブザーバーが呼び出されます。外部ステータスを更新する必要があるかどうかを確認するために、internalStatusIdフィールドが設定されているかどうかがチェックされます。引数にはinternalStatusIdが存在しないため、外部ステータスは設定されません。
  • 第2に、mixinオブザーバが呼び出されます。内部ステータス名はidに変換されます。

この順序はおそらく最初にオブザーバをTicket.jsにロードした後、ミックスインオブザーバをループバックすることによって発生します。

internalStatusIdinternalStatusNameのフィールドの両方を探すように2番目のオブザーバーを変更することはもちろん可能です。しかし、これはコードの重複につながります。特に、ビジネスロジックのオブザーバーが多数あり、このようなUUIDフィールドが数多くあるためです。

私は、これらのオブザーバを実行するためにループバックを伝える方法を探していました。Model.observeFirst()(これは実際には存在しません!)のような単純な関数でさえも、この問題を解決するだろう。私はこれが可能かどうか、もしそうなら、どうしたら見つけられなかったのか。

どのようにこの問題を解決しますか?

答えて

0

ループバックでは、最初にモデルの実装がロードされ、このミックスインの実装後にのみ間違った順序でロードされます。 ループバックでは、イベントのサブスクリプションの標準システムが使用されます。したがって、prependListenerを使用してリスナーを先頭に追加することができます。

// Puts first 
Model.prependListener('before save', function (ctx, next) { 
    let data = ctx.isNewInstance ? ctx.instance : ctx.data; 
    if (data.internalStatusName) { 
    data.internalStatusId = internalStatusNameToIdMap[data.internalStatusName]; 
    delete data.internalStatusName; 
    } 
    next(); 
}); 
関連する問題