简体   繁体   English

在淘汰赛中更干净的数据绑定?

[英]Cleaner data-bind within Knockout?

I'm new to using Knockout and am doing a very basic implementation that changes the color with a observable. 我是使用Knockout的新手,正在做一个非常基本的实现,以可观察的方式更改颜色。 Is there a cleaner way to write the following code? 有没有一种更干净的方法来编写以下代码?

<div class="selected" data-bind="style: { background: fullHexCode(mainScreenNavigationSelector()) !== false ? fullHexCode(mainScreenNavigationSelector()) : 'white' }"></div>

I have this in multiple spots on my page and they all use different params for the fullHexCode() function. 我在页面上的多个位置都有此功能,它们都为fullHexCode()函数使用了不同的参数。 It looks extremely messy. 看起来很乱。 Any help would be great, thanks! 任何帮助将是巨大的,谢谢!

It looks like the logic depends on another observable so you could use a computed observable -- in the snippet below the backgroundColor computed observable depends on the mainScreenNavigationSelector observable. 逻辑似乎依赖于另一个可观察的对象,因此您可以使用计算的可观察对象-在backgroundColor下面的代码段中,计算的可观察对象取决于mainScreenNavigationSelector的可观察对象。

That's just a simple example, you'll have to adjust it to your specific situation. 那只是一个简单的例子,您必须根据具体情况进行调整。

 var MyViewModel = function () { this.mainScreenNavigationSelector = ko.observable(false); this.backgroundColor = ko.computed(function() { return this.mainScreenNavigationSelector() ? 'green' : 'red'; }, this); this.toggleColor = function() { this.mainScreenNavigationSelector(!this.mainScreenNavigationSelector()); } } var viewModel = new MyViewModel(); ko.applyBindings(viewModel); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <div class="selected" data-bind="style: { 'background-color': backgroundColor }"> TEST </div> <button data-bind="click: toggleColor">Toggle Color</button> 

You may deduplicate your HTML code by defining methods in your viewmodel. 您可以通过在viewmodel中定义方法来对HTML代码进行重复数据删除。 Named computeds are even better as they are naturally memoized , that is evaluated only once if used repeatedly in your HTML. 命名计算甚至会更好,因为它们自然会被记住 ,如果在HTML中重复使用,则仅计算一次。

You may also factorize heavy expressions as with: or let: bindings in the parent node. 您还可以像在父节点中使用:let:绑定一样分解重型表达式。 For example: <div class='some-container' data-bind="let: { v: mainScreenNavigationSelector() }">... bindings based on v here... </div> . 例如: <div class='some-container' data-bind="let: { v: mainScreenNavigationSelector() }">... bindings based on v here... </div>

Notice: let is better than with for this purpose. 请注意: 咱们是不是一种更合理。 But it's a new binding which will be available in the next release of KO. 但这是一个新的绑定,它将 KO 的下一版本中提供。 You can polyfill it with a custom binding. 您可以使用自定义绑定对其进行多填充。

When JS expressions can't be avoided in your HTML code, try to make them as slick as possible. 当您的HTML代码中无法避免JS表达式时,请尝试使其尽可能平滑。 For example: 例如:

<div data-bind="style: {
     background: fullHexCode(mainScreenNavigationSelector()) || 'white'
}"></div>

In Javascript, logical operator doesn't return true or false but the actual value of the last evaluated arguments. 在Javascript中,逻辑运算符不会返回true或false,而是最后计算的参数的实际值。 So: 所以:

  • a || || b return a if not "falsy", otherwise b b返回a,如果不是“ falsy”,则返回b
  • a && b return b if a not "falsy", otherwise a a && b如果不是“ fassy”,则返回b,否则返回a

The last idiom is useful in KO bindings because contrary to Angular, KO bindings are regular JS expressions. 最后一个习惯用法在KO绑定中很有用,因为与Angular相反,KO绑定是正则JS表达式。 They fail if some null/undefined occurs in a dot sequence (like ab if a is undefined). 如果在点序列中出现一些null / undefined(如a,如果a未定义),则它们将失败。

So instead of some tertiary operator hell like data-bind="text: object != null ? (object.a != undefined ? object.a : 'None') : 'None'" , just write data-bind="text: object && object.a || 'None'" 因此,只需编写data-bind="text: object && object.a || 'None'" ,而不是像data-bind="text: object != null ? (object.a != undefined ? object.a : 'None') : 'None'"之类的第三级运算符data-bind="text: object != null ? (object.a != undefined ? object.a : 'None') : 'None'" data-bind="text: object && object.a || 'None'"

Also [] and {} are not falsy, and it's actually a good thing. []和{}也不是虚假的,这实际上是一件好事。 It allows to write things like data-bind="foreach: foo.optionalArray || ['default', 'stuff']" 它允许编写诸如data-bind="foreach: foo.optionalArray || ['default', 'stuff']"

However, Number(0) is false. 但是, Number(0)为假。 So beware of something like data-bind="with: object.id && 'saved' || 'new'" which may not work as expected if 0 is a valid object id. 因此,请注意诸如data-bind="with: object.id && 'saved' || 'new'" ,如果0是有效的对象ID,则可能无法按预期工作。

Also this last trick. 这也是最后的把戏。 If data-bind="text: name" fails because name is undefined , then "data-bind="text: name || 'anonymous'" 如果data-bind="text: name"因为name未定义而失败,则"data-bind="text: name || 'anonymous'" "data-bind="text: name || 'anonymous'" will still fail, but "data-bind='text: $data.name || 'anonymous'" "data-bind="text: name || 'anonymous'"仍然会失败,但是"data-bind='text: $data.name || 'anonymous'" "data-bind='text: $data.name || 'anonymous'" will work as expected. As a convention, I write $data.attribute instead of attribute to convey the info about dealing with a optional attribute. "data-bind='text: $data.name || 'anonymous'"会正常工作。根据约定,我写$data.attribute而不是attribute来传达关于处理可选属性的信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM