我有以下javascript:
function RandomViewModel() {
var self = this;
self.RnadomSquaresK = ko.observableArray([
randomSquare(),
randomSquare(),
]);
}
var randomSquare = function() { return ko.observable({
innate: ko.observableArray([
{ star: "test1", Class: "starList", Style: {} },
{ star: "test2", Class: "starList", Style: {display:'inline'} },
{ star: "test3", Class: "starList", Style: {} },
{ star: "test4", Class: "starList", Style: {} }
])
})};
ko.applyBindings(new RandomViewModel());
它基本上创建了两个observableArray的observableArray,每个都有4个元素。
我有以下html:
<script id="starTemplate" type="text/html">
<!-- ko if: ($index >= 0) -->
<div data-bind="text: $index, attr: { class: Class }, style: Style"></div>
<!-- /ko -->
</script>
<div class="starList" data-bind="template: { name: 'starTemplate', foreach: RnadomSquaresK()[0]().innate }"></div>
我希望根据他们所绑定的observableArray打印每个索引来创建div。 (在这种情况下:4个div,因为所有索引应该等于或大于0)
我真正得到的是:空白。
这是JSFiddle链接:http://jsfiddle.net/qrwBE/
如果我将if语句更改为ex:if: $index != 0
,我将打印绑定到数组的所有4个元素,但我不太明白为什么在这种情况下第一个元素(索引0)正在与其他3个元素一起印刷。
我是否错误地使用if
语句?
对正在发生的事情的解释以及关于javascript等的任何其他评论都非常受欢迎。
答案 0 :(得分:3)
所以这里要检查的项目有很多:
为什么你的foreach循环不显示带有索引值的div?
答案是因为你$index()
是一个可观察的,它是函数。所以你必须像我上面演示的那样使用它。 if: $index != 0
工作的原因是因为在javascript中,评估为0的事物是假的,任何非零评估为真(就像你熟悉这些语言一样在c / c ++中。
所以这意味着当你写if: $index != 0
时你真正说的是,函数$index not null or undefined?
是真的,所以它会继续从你的模板输出div。
重构建议:
如果observableArray为空,foreach绑定将自动处理不呈现div标记。这意味着你可以完全删除if check,这也可以修复你的问题。
<script id="starTemplate"a type="text/html">
<div data-bind="text: $index, attr: { class: Class }, style: Style"></div>
</script>
模型更改:
让我们来看看这个功能:
var randomSquare = function() { return ko.observable({
innate: ko.observableArray([
{ star: "test1", Class: "starList", Style: {} },
{ star: "test2", Class: "starList", Style: {display:'inline'} },
{ star: "test3", Class: "starList", Style: {} },
{ star: "test4", Class: "starList", Style: {} }
])
})};
在这里,您将返回一个observable,其中包含一个名为innate的属性,它是一个可观察的数组。为什么不删除它包含在一个observable中,因为它只会使访问数组的语法更加时髦RnadomSquaresK()[0]().innate
而不是这样,以下内容如何:
var randomSquare = function() { return {
innate: ko.observableArray([
{ star: "test1", Class: "starList", Style: {} },
{ star: "test2", Class: "starList", Style: {display:'inline'} },
{ star: "test3", Class: "starList", Style: {} },
{ star: "test4", Class: "starList", Style: {} }
]});
})};
只需将其访问以下内容:RnadomSquaresK()[0].innate
何时制作可观察的内容
请记住,您只需要创建一个可观察的东西......如果您想要在可观察状态发生变化时警告UI或js中的订阅者功能。否则,只需将其设为复制值(普通旧js变量)。
将函数声明与函数表达式混合的危险(提升问题): 这纯粹是js note。
这是一个函数声明function RandomViewModel() { }
这是函数表达式var randomSquare = function() { };
这些与解释者处理它们的方式略有不同。第一个(声明)将被提升到它的父范围的顶部。因此,在随后的代码中,调用RandomViewModel()
将完美地工作,因为它是在解决其他所有问题之前定义的。
然而,第二个(表达式)只会将变量名称提升到顶部,但它的赋值将保持原样,这意味着您的代码将等同于此:
function RandomViewModel() { }
var randomSquare;
randomSquare = function() { };
在您的情况下这将正常工作。但是,当您的模型变得更复杂并且彼此更紧密地耦合时,您可能会遇到类似这种情况的问题:
function RandomViewModel() {
var x = randomSquare(); //<-- would throw an undefined exception here
alert(x);
}
var model = new RandomViewModel();
var randomSquare = function() { return 5; };
这种情况会发生,因为解释程序将您的var randomSquare
提升到范围的顶部,但在RandomViewModel
安全下注,保持一致,不要将这些与appraoches混合搭配写作函数。
答案 1 :(得分:1)
在绑定中执行javascript表达式时,需要获取属性的值:
http://jsfiddle.net/wiredprairie/EWrsF/
if: $index() > 0
使用中:
<script id="starTemplate" type="text/html">
<!-- ko if: $index() > 0 -->
<div data-bind="text: star, attr: { class: Class }, style: Style"></div>
<!-- /ko -->
</script>
我承认你不理解你的其余代码(因为你正在使用的变量名和模式很难理解)。