【问题标题】:Dynamically binding an observable to a input inside a foreach binding using knockoutJS使用 knockoutJS 将 observable 动态绑定到 foreach 绑定中的输入
【发布时间】:2015-06-30 13:22:02
【问题描述】:

我在视图中有下表:

<table class="table">
    <thead>

        <tr data-bind="foreach: ActiveFilters">
            <td>
                <input type="text" data-bind="value: dynamicFilter(Filter), valueUpdate: 'afterkeyup', returnAction:$root.filterData" />
            </td>
        </tr>           
    </thead>
</table>

以下是我的视图模型:

var vm = {
Title: ko.observable(),
Excerpts: ko.observable(),
Content: ko.observable(),
dynamicFilter: function (data) {
    var self = this;
    if (data.Filter == 'Title') {
        return self.Title();
    }
    else if (data.Filter == 'Excerpts') {
        return self.Excerpts();
    }
    else {
        return self.Content();
    }
} };

ActiveFilters 对象有一个名为Filter 的属性,其中包含我想要绑定为页面中输入字段的过滤器的名称。基于Filter 的值,我想动态地将一个可观察对象绑定到输入,如dynamicFilter 函数所示,并使用可观察对象访问用户稍后输入的值以过滤网格中的数据。我们如何在 Knockout 中实现这一点?

编辑

我还有一个问题,我声明视图模型的语法是否正确?(对 KO 还是新手)。假设我在视图模型中有一个名为 filterData 的函数,并且我想在 dynamicFilter 函数中调用该函数,我使用以下语法:

var vm = {
Title: ko.observable(),
Excerpts: ko.observable(),
Content: ko.observable(),
dynamicFilter: function (data) {
    var self = this;
    if (data.Filter == 'Title') {
        return self.Title();
        vm.filterData();// is this correct?
    }
    else if (data.Filter == 'Excerpts') {
        return self.Excerpts();
    }
    else {
        return self.Content();
    }
},
filterData: function(){
 //TODO
} };

上述调用函数的方式正确吗?

【问题讨论】:

  • 过滤器会改变吗?还是保值?

标签: knockout.js


【解决方案1】:

如果Filter不发生变化,可以直接在dynamicFilter中返回observable,而不用去掉括号返回它的值:

var vm = {
Title: ko.observable(),
Excerpts: ko.observable(),
Content: ko.observable(),
dynamicFilter: function (data) {
    var self = this;
    if (data.Filter == 'Title') {
        return self.Title; //instead of return self.Title();
    }
    else if (data.Filter == 'Excerpts') {
        return self.Excerpts;  //instead of return self.Excerpts();
    }
    else {
        return self.Content;  //instead of return self.Content();
    }
} };

另一个可能更具可读性的选项是使用 if 语法:

<tr data-bind="foreach: ActiveFilters">
  <td>
    <!-- ko if: Filter == 'Title' -->
    <input type="text" data-bind="value: Title, valueUpdate: 'afterkeyup', returnAction:$root.filterData" />
    <!-- /ko -->
    <!-- ko if: Filter == 'Excerpts' -->
    <input type="text" data-bind="value: Excerpts, valueUpdate: 'afterkeyup', returnAction:$root.filterData" />
    <!-- /ko -->
    <!-- ko if: Filter != 'Title' && Filter != 'Excerpts' -->
    <input type="text" data-bind="value: Content, valueUpdate: 'afterkeyup', returnAction:$root.filterData" />
    <!-- /ko -->
  </td>
</tr>    

【讨论】:

  • 看起来selfvm 以一种奇怪的方式混合在一起。这会按预期工作吗?也许应该用new 关键字调用dynamicFilter,但是Title 将如何附加到self? (如果我只是很傻,我很抱歉,这只是我以前没有遇到过的一些语法。)
  • 其实“self”在这里是没有用的,它应该保持“this”,但为什么不呢。 “this”是当前对象。您不能在函数中使用“vm”,因为它还没有完成创建。
  • 啊,有道理。谢谢。
  • @GôTô 您发布的两个选项都工作正常,第二个选项似乎更可行,但我还有一个小问题,我已经编辑了我的问题,请回答
  • @seadrag0n 这在上面的评论中得到了回答。请改用this
猜你喜欢
  • 2012-10-15
  • 1970-01-01
  • 2014-02-21
  • 1970-01-01
  • 1970-01-01
  • 2013-02-08
  • 1970-01-01
  • 2015-01-29
  • 1970-01-01
相关资源
最近更新 更多