このページでは、いくつかのソリューションを提供します。関連する部分は次のとおりです。
null オブジェクトからの保護
オブジェクトを含むオブザーバブルがあり、そのオブジェクトのプロパティにバインドしたい場合は、それが null または未定義になる可能性があるかどうかに注意する必要があります。次のようにバインディングを記述できます。
<span data-bind="text: selectedItem() ? selectedItem().name() : 'unknown'"></span>
これを処理する方法はいくつかあります。推奨される方法は、単純にテンプレート バインディングを使用することです。
var viewModel = {
items: ko.observableArray(),
selectedItem: ko.observable()
};
<ul data-bind="template: { name: 'editorTmpl', data: selectedItem }"></ul>
<script id="editorTmpl" type="text/html">
<li>
<input data-bind="value: name" />
</li>
</script>
このメソッドでselectedItem
は、null の場合、何もレンダリングされません。したがって、元のバインディングのように不明は表示されません。selectedItem().name
ただし、バインディングを簡素化するという追加の利点があります。. これが最も簡単な解決策です。
いくつかのオプションを検討するために、いくつかの代替案を以下に示します。
前に行ったように、計算されたオブザーバブルを使用できます。
viewModel.selectedItemName = ko.computed(function() {
var selected = this.selected();
return selected ? selected.name() : 'unknown';
}, viewModel);
ただし、これにより、ビュー モデルが不要になる可能性があり、多くのプロパティに対してこれを繰り返さなければならない可能性があります。
次のようなカスタム バインディングを使用できます。
<div data-bind="safeText: { value: selectedItem, property: 'name', default: 'unknown' }"></div>
ko.bindingHandlers.safeText = {
update: function(element, valueAccessor, allBindingsAccessor) {
var options = ko.utils.unwrapObservable(valueAccessor()),
value = ko.utils.unwrapObservable(options.value),
property = ko.utils.unwrapObservable(options.property),
fallback = ko.utils.unwrapObservable(options.default) || "",
text;
text = value ? (options.property ? value[property] : value) : fallback;
ko.bindingHandlers.text.update(element, function() { return text; });
}
};
これはオリジナルよりも優れていますか?おそらくそうではないと思います。バインディングで JavaScript を回避しますが、それでもかなり冗長です。
もう 1 つのオプションは、実際の値を null にすることを許可しながら、プロパティにアクセスするための安全な方法を提供する拡張オブザーバブルを作成することです。次のようになります。
ko.safeObservable = function(initialValue) {
var result = ko.observable(initialValue);
result.safe = ko.dependentObservable(function() {
return result() || {};
});
return result;
};
したがって、これは常に空のオブジェクトを返す safe という名前の計算されたオブザーバブルも公開する単なるオブザーバブルですが、実際のオブザーバブルは引き続き null を格納できます。
これで、次のようにバインドできます。
<div data-bind="text: selectedItem.safe().name"></div>
不明な値が null の場合は表示されませんが、selectedItem
null の場合は少なくともエラーは発生しません。
この場合、特にバインドするこれらのプロパティが多数ある場合は、テンプレート バインディングを使用することをお勧めします。