在KO中使用with
会导致元素仅在data-bind的上下文可用时呈现。如果我有在页面加载上运行的脚本并且负责样式化HTML元素,那么如果我在数据绑定使用document.getElementById
的元素上调用with
,则会得到null。这是一些伪代码:
HTML:
<section data-bind="with: selectedView" id="sec">
<span data-bind="text: title" id="span"></span>
</section>
运行onload的JS:
var PseudoViewModel = { ... };
ko.applyBindings(PseudoViewModel);
var x = document.getElementById("span"); // this is null
动态设计元素的最佳做法是什么?感谢。
答案 0 :(得分:1)
如果您在元素存在时执行该代码(example),那么您正在做的工作应该有效。
在您的示例中, (原来这是问题代码中的错误,您打算定位#sec
是具有with
绑定的元素。如果with
绑定(示例中为#sec
)的值为with
,则selectedView
将省略null
的后代元素或undefined.
所以#sec
将始终存在,而不是其中的范围。 (Example)span
。)
动态设计元素的最佳做法是什么?
最佳做法是使用CSS而不是JavaScript代码来设置元素样式。可能与css
绑定相结合,但不一定。
另一种选择是进行自定义绑定,将样式作为KO内容的一部分。自定义绑定在KO中很常见。由于KO知道它没有呈现元素,因此它不会对它运行自定义绑定,并且没有错误。
当然,如果您因为使用了with
或if
而确实有可能存在或不存在的元素,请在使用之前测试它们是否存在:
var x = document.getElementById("span");
if (x) {
// Do stuff here
}
但是,再次提出建议:
使用CSS而非JavaScript来设置元素样式(可能与css
绑定一起应用于它的类);或
如果必须运行每个元素的代码,请使用自定义绑定(这里很棒的是你定义它们并重用它们);或
使用警卫(if (x) { ... }
)
这是一个自定义绑定的示例,如果绑定的值超过12个字符,则该元素的颜色为红色,否则为蓝色:
ko.bindingHandlers.colorByLength = {
update: function(element, valueAccessor/*, allBindings, viewModel, bindingContext*/) {
var val = ko.unwrap(valueAccessor());
element.style.color = (val && val.length > 12) ? "red" : "blue";
}
};
完整示例:Live Copy
<!DOCTYPE html>
<html>
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-min.js"></script>
<meta charset=utf-8 />
<title>Example Custom Binding</title>
</head>
<body>
<section data-bind="with: selectedView" id="sec">
<span data-bind="text: title, colorByLength: title" id="span"></span>
</section>
<section data-bind="with: anotherView" id="sec">
<span data-bind="text: title, colorByLength: title" id="span"></span>
</section>
<section data-bind="with: nullView" id="sec">
<span data-bind="text: title, colorByLength: title" id="span"></span>
</section>
<script>
(function() {
"use strict";
// Custom binding
ko.bindingHandlers.colorByLength = {
update: function(element, valueAccessor/*, allBindings, viewModel, bindingContext*/) {
var val = ko.unwrap(valueAccessor());
element.style.color = (val && val.length > 12) ? "red" : "blue";
}
};
var PseudoViewModel = {
// This one will be red
selectedView: {
title: "This is the title"
},
// This one will be blue
anotherView: {
title: "Short title"
},
// And of course, this one isn't rendered at all
nullView: null
};
ko.applyBindings(PseudoViewModel);
})();
</script>
</body>
</html>
答案 1 :(得分:0)
如果在数据绑定上下文不可用时元素无法呈现所需的行为,那么您必须在JavaScript中防范:
function doThatThingOnPageLoad() {
var elem = document.getElementById("sec");
if (elem == null) return;
continueDoingThatThingWith(elem);
}
您的JavaScript应该将此元素视为可选元素,因为它可能不存在。