2016-08-24 55 views
2

我試圖將一個異步值綁定到我的Aurelia模板之一,顯然我得到的是[object Promise]作爲回報。在Aurelia異步綁定

我發現這篇文章http://www.sobell.net/aurelia-async-bindings/這很好地解釋瞭如何使用綁定行爲,看起來像這樣來解決這個問題:

// http://www.sobell.net/aurelia-async-bindings/ 
export class asyncBindingBehavior { 
    bind (binding, source) { 
     binding.originalUpdateTarget = binding.updateTarget; 

     binding.updateTarget = a => { 
      if (typeof a.then === 'function') { 
       binding.originalUpdateTarget('...'); 

       a.then(d => { 
        binding.originalUpdateTarget(d); 
       }); 
      } 
      else { 
       binding.originalUpdateTarget(a); 
      } 
     }; 
    } 

    unbind (binding) { 
     binding.updateTarget = binding.originalUpdateTarget; 
     binding.originalUpdateTarget = null; 
    } 
} 

這完美的作品時,承諾用細繩或其他非對象像解析變量。

但是,如果我的承諾用一個對象來解決呢?我將如何去訪問該對象內需要的屬性?

因爲如果我這樣做:${object.property & async}在我的模板裏面,那麼它會失敗,因爲object.property不是承諾 - 只有object是。

我加入一個黑客位的,讓我指定屬性作爲參數傳遞給async,像這樣:${object & async:'property'}並更新了綁定的行爲,例如:

// http://www.sobell.net/aurelia-async-bindings/ 
export class asyncBindingBehavior { 
    bind (binding, source, property) { 
     binding.originalUpdateTarget = binding.updateTarget; 

     binding.updateTarget = a => { 
      if (typeof a.then === 'function') { 
       binding.originalUpdateTarget('...'); 

       a.then(d => { 
        if (property) { 
         binding.originalUpdateTarget(d[property]); 
        } 
        else { 
         binding.originalUpdateTarget(d); 
        } 
       }); 
      } 
      else { 
       binding.originalUpdateTarget(a); 
      } 
     }; 
    } 

    unbind (binding) { 
     binding.updateTarget = binding.originalUpdateTarget; 
     binding.originalUpdateTarget = null; 
    } 
} 

但這種感覺很像一個黑客給我,也不會讓我訪問任何更深的屬性,如object.parent.child

我還在GitHub上發現了這個(相當老)的問題:https://github.com/aurelia/templating/issues/81他們使用getValue方法。我從來沒有聽說過這種方法,並試圖使用它失敗,所以我不知道這是如何工作...

任何想法?

回答

1

您可以通過將函數指定爲第三個參數來避開您的難題,使其具有比簡單屬性提取更多的靈活性。

你可以寫這樣的:(?)

export class asyncBindingBehavior { 
    bind (binding, source, transformer="default") { 
     binding.originalUpdateTarget = binding.updateTarget; 
     binding.updateTarget = a => { 
      if (typeof a.then === 'function') { 
       binding.originalUpdateTarget('...'); 
       a.then(d => binding.originalUpdateTarget(transformFunctions[transformer](d))); 
      } else { 
       binding.originalUpdateTarget(a); 
      } 
     }; 
    } 
    unbind (binding) { 
     binding.updateTarget = binding.originalUpdateTarget; 
     binding.originalUpdateTarget = null; 
    } 
} 

transformFunctions查找是必要的,因爲奧裏利亞綁定指定爲HTML-ebbedded或模板指令的方式(即所有PARAMS必須爲String) 。 (?Value Converters)除非奧裏利亞提供了一個更好的方式更好的方式來「傳遞函數」,你會寫是這樣的:

export var transformFunctions = { 
    default: (d) => d, 
    transform1: (d) => d.someProperty, 
    transform2: (d) => d.someProperty.someOtherProperty, 
    transform3: someFunction, 
    transform4: someOtherFunction.bind(null, someData); 
} 

當然,你能不能把功能更好的名字。

+1

嗯我明白你的意思了。我想一個函數會更有意義,因爲我可以做任何我想提取我需要的值的東西。但是,這真的是最好的方式嗎?理想情況下,我會_love_像'$ {object.property&async}'這樣的東西。也許我可以從「property」中「步行」到'object'? – powerbuoy

+1

當然,您可以傳遞一個「dot.separated.property.string」,'.split('。')'然後向下鑽取以提取'd [「dot」] [「separated」] [「property」 ] [「string」]'但這肯定比函數更不靈活,可以說更加混亂。 –

+0

好的,我會稍後再打開這個問題,看看我是否還有更多的建議。 – powerbuoy