从HTML标记给予初始值可观察(Giving initial value to observable

2019-06-27 08:55发布

我试图创建一个HtmlHelper扩展输出HTML的视图。 在这个HTML我连线了一些KnockoutJS结合。 我是新来KO所以我仍然得到一些事情做挣扎。 不管怎样,我想要做的是产生必然可观我的客户端代码输入字段(在服务器端代码),然后通过隐藏字段的值设置的观测值的初始值。 不幸的是,这是不是为我工作。 所以,我想知道是否有什么办法,我可以完成这件事(即使我必须这样做完全不同)。

这里就是我基本上做的:

在我的客户端视图模型我有以下几点:

self.dataSource = ko.observable();
self.pageSize = ko.observable();

而我的扩展方法输出以下内容:

<input type="hidden" value="/Employee/Get" data-bind="value: dataSource" />
<input type="hidden" value="30" data-bind="value: pageSize" />

但是页面呈现的时候,当我检查的元素我注意到value输入字段被设置为空字符串,我相信这是因为道路被宣布可观。 但是,有没有办法可以覆盖这种行为还是什么?

Answer 1:

你可以用它来保持你的代码有点吸尘器一种选择是使用包装的值通过使元件的当前值初始化它绑定自定义绑定。

你甚至可以把它在你的视图模型创造可观,如果他们不存在。

结合可能看起来是这样的:

ko.bindingHandlers.valueWithInit = {
    init: function(element, valueAccessor, allBindingsAccessor, data) {
        var property = valueAccessor(),
            value = element.value;

        //create the observable, if it doesn't exist 
        if (!ko.isWriteableObservable(data[property])) {
            data[property] = ko.observable();
        }

        data[property](value);

        ko.applyBindingsToNode(element, { value: data[property] });
    }
};

你会使用它,如:

<input value="someValue" data-bind="valueWithInit: 'firstName'" />

请注意,属性名是在引号,这使得结合创建它,如果它不存在,而不是从一个未定义的值报错了。

下面是一个示例: http://jsfiddle.net/rniemeyer/BnDh6



Answer 2:

有点晚了这里。 我实际上并没有满足于RP的答案,因为它打破淘汰赛的声明性质。 特别是,如果你使用valueWithInit来定义你的财产,你不能在更早的结合使用 。 这里有一个自己的jsfiddle证明的叉 。

您可以使用同样的方式,但它仍然是引擎盖下宽文档声明:

<input data-bind="valueWithInit: firstName" value="Joe" />

的想法扩展,你也可以用这个来初始化和绑定分离:

<input data-bind="initValue: lastName, value: lastName" value="Smith" />

这是一个有点多余,但是当你使用一个插件,而不是内置的绑定成为有用:

<input data-bind="initValue: lastName, myPlugin: lastName" value="Smith" />

拓展多一点,我也需要一种方法来初始化复选框:

<input type="checkbox" data-bind="checkedWithInit: isEmployed" checked />

这里是处理:

ko.bindingHandlers.initValue = {
    init: function(element, valueAccessor) {
        var value = valueAccessor();
        if (!ko.isWriteableObservable(value)) {
            throw new Error('Knockout "initValue" binding expects an observable.');
        }
        value(element.value);
    }
};

ko.bindingHandlers.initChecked = {
    init: function(element, valueAccessor) {
        var value = valueAccessor();
        if (!ko.isWriteableObservable(value)) {
            throw new Error('Knockout "initChecked" binding expects an observable.');
        }
        value(element.checked);
    }
};

ko.bindingHandlers.valueWithInit = {
    init: function(element, valueAccessor, allBindings, data, context) {
        ko.applyBindingsToNode(element, { initValue: valueAccessor() }, context);
        ko.applyBindingsToNode(element, { value: valueAccessor() }, context);
    }
};

ko.bindingHandlers.checkedWithInit = {
    init: function(element, valueAccessor, allBindings, data, context) {
        ko.applyBindingsToNode(element, { initChecked: valueAccessor() }, context);
        ko.applyBindingsToNode(element, { checked: valueAccessor() }, context);
    }
};

通知valueWithInit只需使用initValue引擎盖下。

看到它在行动的jsfiddle 。



Answer 3:

如果自定义绑定是太重量级那么一个简单的解决方案是从DOM初始化可观。

例如,给定以下HTML形式:

<form name="person">
  <input type="text" name="firstName" value="Joe" data-bind="value: firstName"/>
</form>

然后如下淘汰赛会被初始化:

ko.applyBindings({
  firstName: ko.observable(document.forms['person']['firstName'].value)
});


Answer 4:

你可以简单地使用自定义绑定和分配值到现有的观测:

ko.bindingHandlers.yourBindingName = {
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        viewModel.dataSource($(".dataSource").val());
        viewModel.pageSize($(".pageSize").val());
    }
};

然后,只需添加一个类或一个ID输入和data-bind="yourBindingName"含有它们的HTML元素。



文章来源: Giving initial value to observable from the HTML markup