如何保持从服务器加载的数据不被“空白”?通过Knockout JS加载页面
How do I keep data loaded from the server from getting "blanked out" by Knockout JS on page load?
我试图理解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);
那么我需要做些什么来显示/保存数据呢?
Knockout就不能像Angular JS那样保存数据吗?
注意我使用Yii MVC框架来处理很多服务器端东西。使用它在页面加载时加载数据,节省了我编写大量JS Ajax代码的时间。我想使用Knockout来减少我拥有的jQuery代码的数量,而不是添加到它:)
另一种方法是构造视图模型,将服务器上的值直接提供给可观察对象。
<span data-bind="text: name"></span>
var viewModel = {
name: ko.observable(<?php echo $data->name; ?>);
};
ko.applyBindings();
试图从HTML中初始化一个可观察对象的值是很危险的,因为有很多方法可以重置可观察对象的值,特别是当一个元素包含在一个使用显式/隐式模板的父绑定中,比如if
绑定。
<div data-bind="if: someFlag">
<span data-bind="text: name">John Doe</span>
<div>
在上面的例子中,每次someFlag
值从false变为true时,span元素上的文本绑定将被重新初始化。
这里有两种方法可以尝试避免两次声明数据(注意它们不直接提供将数据保存在html文件中的方法):
解决方案1:把你的默认模型放在一个单独的js/php文件创建一个php文件
var defaultVm = {
name: '<?php echo $data->name; ?>',
anyVariable: '<?php echo $data->anyVariable; ?>'
}
然后你把这个php文件作为一个js文件,用它初始化你的视图模型:
var viewModel = {
name: ko.observable(defaultVm.name);
anyVariable: ko.observable(defaultVm.anyVariable);
};
ko.applyBindings(viewModel);
方案二:使用ko。映射插件
创建一个php文件
{
"name": "<?php echo $data->name; ?>",
"anyVariable": "<?php echo $data->anyVariable; ?>"
}
然后在js中,你可以使用ko。映射插件:
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);
}
您可以创建一个自定义绑定处理程序来做到这一点:
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);
}
};
然后你可以像这样绑定你的视图模型:
Name: <span data-bind="textInitialized: name" class="name">John B</span>
EDIT after jsFiddle:
您已经在jsFiddle中创建了一个完全不同的东西。几件事:
- 在你的autocomplethandler中,你使用我提供的代码,但是:你想设置"value"属性,而不是innerHTML,所以你应该把它改成
element.value
而不是element.innerHTML
。你有一个自动完成绑定和一个值绑定。它们都在value属性上工作(如果您遵循我的第一个注释)。第二个将在第一个之后出现,并撤销该更改。我已经修改了小提琴与这些变化:http://jsfiddle.net/P8N77/24/
- 无法在通过jQuery的ajax加载的页面中执行javascript
- 通过单击动态加载的表中同一行的另一个字段来更新一行的字段
- 如何通过ajax增加/减少PHP变量值并重新加载函数
- 在通过child.print()打印之前,我如何等待图像加载到我的新窗口中
- 通过浏览器加载页面时触发加载脚本(js或jQuery)'s”;返回“;作用
- UIWebview赢得't通过基本身份验证加载动态加载的资源(通过jQuery mobile)
- Chrome扩展无法通过清单加载外部javascript
- 通过加载函数发送一个变量
- 如何通过JavaScript了解当前加载页面的mime类型或内容类型
- 通过AJAX加载页面并执行javascript和CSS
- Javascript函数加载(通过引用?)
- JQuery不加载通过服务获得的效果
- 如何在自定义模式对话框中加载通过 AJAX 调用返回的 JSON 数据
- 通过单击和加载通过 ajax 加载内容
- Jquery实时加载-通过ajax加载表单
- JS中的HTML ?或在单独的html文件(加载通过$.Ajax或$.load)
- 这是有可能检测点击广告加载通过iframe
- Ckeditor不加载通过ajax在弹出对话框中生成的元素
- Ckeditor不加载通过ajax调用生成的元素
- 未加载通过Chrome扩展插件注入的JavaScript