binding - 当源为 null/未定义时 KnockoutJS 绑定(bind)

标签 binding knockout.js

是否有更短/更干净的方法来进行空/未定义测试?

<select data-bind="options: SelectedBusinessLine() ? SelectedBusinessLine().Clusters() : [],
                               optionsText: 'Title',
                               value: SelectedCluster,
                               optionsCaption: 'Select Cluster..'">
            </select>

而不是

data-bind="options: SelectedBusinessLine() ? SelectedBusinessLine().Clusters() : [],

我想要

data-bind="options: SelectedBusinessLine().Clusters(),

给予或接受()

或者至少是一个更简单的空运算符检查“??”选定的业务线 ?? []

或者一个绑定(bind)参数来自动检查 null 或静默失败。

如果这可能的话有什么想法吗?

最佳答案

This page提供了几种解决方案。相关部分是这个:

防止空对象

如果您有一个包含对象的可观察对象,并且您想要绑定(bind)到该对象的属性,那么您需要小心它是否有可能为 null 或未定义。您可以像这样编写绑定(bind):

<span data-bind="text: selectedItem() ? selectedItem().name() : 'unknown'"></span>

有多种方法可以处理这个问题。首选方法是简单地使用模板绑定(bind):

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,则它不会呈现任何内容。因此,您不会像在原始绑定(bind)中那样看到未知。但是,它确实具有简化绑定(bind)的额外好处,因为您现在可以直接指定属性名称,而不是 selectedItem().name。这是最简单的解决方案。

只是为了探索一些选项,这里有一些替代方案:

您可以使用计算的可观察量,就像我们之前所做的那样。

viewModel.selectedItemName = ko.computed(function() {
  var selected = this.selected();
  return selected ? selected.name() : 'unknown';
}, viewModel);

但是,这再次给我们的 View 模型增加了一些我们可能不希望的膨胀,并且我们可能必须对许多属性重复此操作。

您可以使用自定义绑定(bind),例如:

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

这个比原版好吗?我想说可能不会。它确实避免了我们绑定(bind)中的 JavaScript,但它仍然相当冗长。

另一个选择是创建一个增强的可观察量,它提供一种安全的方式来访问属性,同时仍然允许实际值为空。可能看起来像:

ko.safeObservable = function(initialValue) {
  var result = ko.observable(initialValue);
  result.safe = ko.dependentObservable(function() {
    return result() || {};
  });

  return result;
};

因此,这只是一个可观察量,它还公开了一个名为 safe 的计算可观察量,该可观察量始终返回一个空对象,但实际可观察​​量可以继续存储 null。

现在,您可以像这样绑定(bind)它:

<div data-bind="text: selectedItem.safe().name"></div>

当未知值为 null 时,您不会看到该值,但当 selectedItem 为 null 时,至少不会导致错误。

我确实认为在这种情况下,首选选项是使用模板绑定(bind),特别是如果您有许多要绑定(bind)的属性。

关于binding - 当源为 null/未定义时 KnockoutJS 绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11387501/

相关文章:

knockout.js - KnockoutJS 通过另一个 ObservableArray 过滤 ObservableArray

c# - 如何将VM中的可为空 bool 值绑定(bind)到RadRadioButton

java - 是否可以使用 Bindings API 将 ObservableList 的非空状态绑定(bind)到 ObjectProperty 中?

Python:新对象使用先前对象的属性

javascript - 如何使用 JavaScript/Jquery/Knockout JS 将数字数组绑定(bind)到范围 slider

javascript - 如何使用 Knockout 取消选择控件上的更改事件?

silverlight - XAML 绑定(bind) silverlight

select - 你如何使用 knockout.js 来构建一个 <select> 元素的 <option> 包含文本和值,并设置一个初始选择的值?

javascript - knockout : editing data with easy rollback to previous value

knockout.js - knockout 嵌套的 observableArrays 似乎是未定义的,而不是空的。