当源为空/未定义时 KnockoutJS 绑定 [英] KnockoutJS binding when source is null/undefined

查看:18
本文介绍了当源为空/未定义时 KnockoutJS 绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is there a shorter/cleaner way to do the null/undefined testing?

<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(),

给予或接受 ()

或者至少是一个更简单的空操作符检查 '??'SelectedBusinessLine ??[]

Or at least a simpler null operator check '??' SelectedBusinessLine ?? []

或者一个绑定参数来自动检查 null 或无提示失败.

Or a binding param to auto check for null or silent fail.

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

Any ideas if this is possible?

推荐答案

本页提供了多种解决方案.相关部分是这个:

This page provides several solutions. The relevant part is this one:

防止空对象

如果你有一个包含对象的 observable 并且你想绑定到该对象的属性,那么你需要小心它是否有可能为空或未定义.你可以这样写你的绑定:

If you have an observable that contains an object and you want to bind to properties of that object, then you need to be careful if there is a chance that it can be null or undefined. You may write your binding like:

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

有很多方法可以处理这个问题.首选方法是简单地使用模板绑定:

There are a number of ways to handle this one. The preferred way would be to simply use the template binding:

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.这是最简单的解决方案.

With this method, if selectedItem is null, then it just won’t render anything. So, you would not see unknown as you would have in the original binding. However, it does have the added benefit of simplifying your bindings, as you can now just specify your property names directly rather than selectedItem().name. This is the easiest solution.

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

Just for the sake of exploring some options, here are a few alternatives:

你可以像我们以前那样使用计算的 observable.

You could use a computed observable, as we did before.

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

然而,这再次给我们的视图模型增加了一些我们可能不想要的膨胀,我们可能不得不为许多属性重复这一点.

However, this again adds some bloat to our view model that we may not want and we might have to repeat this for many properties.

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

You could use a custom binding like:

<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,但它仍然非常冗长.

Is this better than the original? I would say probably not. It does avoid the JavaScript in our binding, but it is still pretty verbose.

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

One other option would be to create an augmented observable that provides a safe way to access properties while still allowing the actual value to be null. Could look like:

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

  return result;
};

所以,这只是一个 observable,它也暴露了一个名为 safe 的计算出的 observable,它总是返回一个空对象,但实际的 observable 可以继续存储 null.

So, this is just an observable that also exposes a computed observable named safe that will always return an empty object, but the actual observable can continue to store null.

现在,您可以像这样绑定到它:

Now, you could bind to it like:

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

当未知值为空时,您不会看到未知值,但至少在selectedItem为空时不会导致错误.

You would not see the unknown value when it is null, but it at least would not cause an error when selectedItem is null.

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

I do think that the preferred option would be using the template binding in this case, especially if you have many of these properties to bind against.

这篇关于当源为空/未定义时 KnockoutJS 绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆