【问题标题】:Updating dynamically generated button text using knockout使用敲除更新动态生成的按钮文本
【发布时间】:2014-06-27 07:17:21
【问题描述】:

我正在动态地将数据加载到网格中,并且每一行都有“添加”按钮。

btn = "<a id='btnRow' data-bind='click: function()
    { ClickAdd(\"" + rowObject.Id+ "\")}'>" +
    "<i ></i><span data-bind='text:$root.StrResources.BtnAdd'/></a>";

如上所示,我正在使用 data-bind 设置按钮的文本

现在单击按钮时,我想将文本从“添加”更改为“已选择” 我在 javascript 对象中有属性作为

StrResources: {
    BtnView: ko.observable("View"),
    BtnAdd: ko.observable("Add"),
    BtnSelected: ko.observable("Selected"),
},

在 java 脚本对象中我确实有方法来执行添加操作

empObject.ViewModel.ClickAdd = function (objectDN, objectName) {
    // here i want to write code to change the text.
};

我该怎么做?

【问题讨论】:

  • StrResources 对象中最后一项后的逗号有误。

标签: javascript knockout.js


【解决方案1】:

您只需将文本绑定到可观察对象:

<button data-bind="click: changeButtonText, text: buttonText"></button>

然后在点击函数中,你会改变文本:

var Row = function(row) {
    var self = this;

    self.buttonText = ko.observable('Add');

    self.changeButtonText = function() {
        self.buttonText('Selected');
    };
};

http://jsfiddle.net/Wk7dr/3/

【讨论】:

    【解决方案2】:

    我明白你在尝试什么,但我不确定这是做事的正确方式。您的资源对象包含一些可观察对象,但可观察对象的意义在于,当您更改它们时,您之前绑定的 UI 会更改以反映可观察对象中的更改。我的困惑是您的资源应该是静态的。

    然后我看到您正在绑定到这些资源,但是您绑定按钮文本的方法被硬编码为使用 StrResources.BtnAdd 资源;如果您将该 observable 更新为“已选择”,则绑定到 StrResources.BtnAdd 的所有按钮都将更改为具有“已选择”的文本。

    您真正需要的是一种为每个按钮指定文本的方法,而不是将所有按钮绑定到一个 observable。

    阅读您问题的字里行间,我实现了一个simple grid here,我认为它符合您的要求:

    http://jsbin.com/finucabo/1/edit?html,js,output

    感兴趣的部分是:

    var model = {
        grid: {
            row: ko.observableArray(),
    
            selected: ko.observable()
        },
    
        buttonText: function (row) {
            return model.grid.selected() === row ? 'Selected' : 'Add';
        },
    
        buttonClick: function (row) {
            if (model.grid.selected() === row) {
                model.grid.selected(null);
            } else {
                model.grid.selected(row);
            }
        }
    };
    

    还有绑定:

    <!-- ko foreach: grid.row -->
    <tr>
        <td data-bind="text: first"></td>
        <td data-bind="text: last"></td>
        <td data-bind="text: email"></td>
        <td>
            <button
                type="button"
                data-bind="click: $root.buttonClick, text: $root.buttonText($data)">                    
            </button>
        </td>
    </tr>
    <!-- /ko -->
    

    请注意,单击按钮只是将当前行存储到 model.grid.selected observable 中。这将导致 buttonText 重新评估文本绑定。

    希望对你有所帮助。

    编辑:

    关于能够选择多行,您可以将 selected 更改为可观察数组。

    我在这里更新了 jsbin:http://jsbin.com/finucabo/2/edit

    变化是:

    // Helper function added.
    function arrayContains(anArray, aValue) {
        return ko.utils.arrayFirst(anArray(), function (v) {
            return v === aValue;
        }) !== null;
    }
    
    var model = {
        grid: {
            row: ko.observableArray(),
    
            // Now using an observable array.
            selected: ko.observableArray()
        },
    
        buttonText: function (row) {
            // Modify to use observable array.
            return arrayContains(model.grid.selected, row) ? 'Selected' : 'Add';
        },
    
        buttonClick: function (row) {
            // Modify to use observable array.
            if (arrayContains(model.grid.selected, row)) {
                model.grid.selected.remove(row);
            } else {
                model.grid.selected.push(row);
            }
        }
    };
    

    【讨论】:

    • 谢谢,你很亲密。但我应该允许选择多个记录。我的意思是,可以“选择”更多行。实际上我有两个网格,源和目标。用户可以从“源”中选择行并添加到“目标”。我不希望用户将重复记录添加到目标网格。这就是为什么我要禁用“添加”按钮并将文本更改为“已选择”。这样用户就不能将多条记录添加到目标网格中。
    • @iShareHappyCode 我添加了具有多选功能的新版本的 jsbin。想法是一样的,我们只是为多选项目使用一个可观察的数组。稍后,当您从源复制到目标网格时,您可以只复制“选定”中的行,然后在将值写入目标后清除“选定”。希望对您有所帮助。
    猜你喜欢
    • 1970-01-01
    • 2019-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-24
    • 2019-06-02
    • 2012-10-23
    • 1970-01-01
    相关资源
    最近更新 更多