如何保持从服务器加载的数据不被删除"由Knockout JS在页面加载?

时间:2014-06-01 21:26:46

标签: javascript jquery knockout.js

我试图了解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代码量,而不是添加它:)

3 个答案:

答案 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文件中的方法):

解决方案1:将您的默认模型放在单独的js / php文件

使用以下命令创建一个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); 

解决方案2:使用ko.mapping插件

使用以下命令创建一个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中创造了一个完全不同的东西。 一些事情:

  1. 在autocomplethandler中,您使用我提供的代码,但是:您想要设置&#34;值&#34; -attribute,而不是innerHTML,因此您应该将其更改为element.value而不是{ {1}}。
  2. 您同时拥有自动完成绑定和值绑定。它们都在value-attribute上工作(如果你按照我的第一条评论)。第二个将在第一个之后进入并撤消该更改。
  3. 我已经修改了这些变化的小提琴:http://jsfiddle.net/P8N77/24/