我试图了解Knockout JS。困扰我的是我绑定的数据消隐。这很烦人,因为我想显示我从服务器检索的数据。
一个例子:
Name: <span class="name"><?php echo $data->name; ?></span>
结果是:Name: John B
现在,如果我将这与Knockout数据绑定到此:
Name: <span data-bind="text: name" class="name"><?php echo $data->name; ?></span>
结果是:Name:
JS将是这样的:
var viewModel = {
name: ko.observable() // Initially blank <--- this is the culprit
};
ko.applyBindings(viewModel);
那么为了显示/保存数据我需要做什么呢? 无法以某种方式敲除像Angular JS这样的数据吗?
注意 我使用Yii MVC框架来处理很多服务器端的东西。使用它来加载页面加载数据,使我免于编写大量的JS Ajax代码。我想使用Knockout来减少我拥有的jQuery代码量,而不是添加它:)
答案 0 :(得分:2)
另一种方法是构造viewmodel,将服务器中的值直接提供给observable。
<span data-bind="text: name"></span>
var viewModel = {
name: ko.observable(<?php echo $data->name; ?>);
};
ko.applyBindings();
尝试从HTML初始化一个可观察的值是危险的,因为有很多方法可以重置observable值,特别是如果一个元素包含在使用显式/的父绑定中隐式模板,如if
绑定。
<div data-bind="if: someFlag">
<span data-bind="text: name">John Doe</span>
<div>
在上面的示例中,每当someFlag
值从false变为true时,span元素上的文本绑定将被重新初始化。
答案 1 :(得分:2)
以下是两种解决方法,您可以尝试避免两次声明数据(请注意,它们并不直接提供将数据保存在html文件中的方法):
使用以下命令创建一个php文件:
var defaultVm = {
name: '<?php echo $data->name; ?>',
anyVariable: '<?php echo $data->anyVariable; ?>'
}
然后你将这个php文件包含为js文件并用它初始化你的viewmodel:
var viewModel = {
name: ko.observable(defaultVm.name);
anyVariable: ko.observable(defaultVm.anyVariable);
};
ko.applyBindings(viewModel);
使用以下命令创建一个php文件:
{
"name": "<?php echo $data->name; ?>",
"anyVariable": "<?php echo $data->anyVariable; ?>"
}
然后在你的js中,你可以使用ko.mapping插件:
var viewModel = function (data) {
ko.mapping.fromJS(data, {}, this);
};
ko.applyBindings(new viewModel(getYourPhpFileTheWayYoulike));
这允许您使用以下内容异步获取数据(如果需要):
$.getJSON("yourphpmodelurl", function (data) {
ViewModelInstance = new viewModel(data);
ko.applyBindings(ViewModelInstance);
}
答案 2 :(得分:1)
您可以创建自定义绑定处理程序来执行此操作:
ko.bindingHandlers.textInitialized= {
init: function (element, valueAccessor) {
valueAccessor()(element.innerHTML); // get the current value and update the observable
},
update: function (element, valueAccessor) {
var value = valueAccessor();
element.innerHTML = ko.utils.unwrapObservable(value);
}
};
然后你可以像这样绑定你的viewmodel:
Name: <span data-bind="textInitialized: name" class="name">John B</span>
在jsFiddle之后编辑:
你在jsFiddle中创造了一个完全不同的东西。 一些事情:
element.value
而不是{ {1}}。 我已经修改了这些变化的小提琴:http://jsfiddle.net/P8N77/24/