尝试使用knockout.js为元素设置ID并获取未定义

时间:2017-08-09 10:59:49

标签: javascript knockout.js

如果我在这里做了一些愚蠢的事情,我是新来的,对于JavaScript来说是个新手,所以道歉......

我正在使用knockout.js(3.4.2)维护一个依赖列表,我有添加和删除工作正常但我想在一个元素上设置一个ID,以允许我只读它。 我已将我的代码基于淘汰赛示例,他们的工作示例可以在这里看到:Demo

当我运行我的代码时,ID被设置为undefined:

<input data-bind="uniqueId: dependantName, value: dependantName" id="undefined" type="text">

我的JS小提琴代码 https://jsfiddle.net/zacmarshall/khb13ha4/

HTML:

<!DOCTYPE html>
<head>
    <script src="javascripts/vendor/knockout-3.4.2.js" type="text/javascript"></script>
    <script src="javascripts/vendor/jquery-1.11.1.min.js"></script>
    <script src="javascripts/vendor/jquery.validate.js" type="text/javascript"></script>
<head>


<body>

    <input data-bind="value: newDependantName" />
    <input data-bind="value: newDobDD" />
    <button data-bind="click: addDependant">Add</button>

    <pre data-bind="text: ko.toJSON($data, null, 2)"></pre>

    <table>
        <thead>
            <tr>
                <th>Name</th>
                <th>Date of Birth</th> 
                <th></th>
            </tr>
        </thead>
        <tbody id="qualifications-summary" data-bind="foreach: dependants">
            <!--div data-bind="uniqueId: dependantName"-->
            <div>
                <tr>

                    <td><label data-bind="uniqueFor: dependantName">Before</label>
                        <input type="text" data-bind="uniqueId: dependantName, value: dependantName"/>
                    </td>
                    <td><input data-bind="value: dobDD" /></td> 
                    <td><input data-bind="value: itemIndex"/></td> 
                    <td><a href="#" data-bind="click: $root.removeDependant">Remove</a></td>

                </tr>
            </div>
        </tbody>

    </table>

</body>

的javascript:

function Dependant(data) {
    this.itemIndex = ko.observable(0);
    this.dependantName = ko.observable(data.dependantName);
    this.dobDD = ko.observable(data.dobDD);
    this.readOnly = ko.observable(data.readOnly);
    this.showEditButton = ko.observable(data.showEditButton);
}



function DependantListViewModel() {
    // Data
    var self = this;

    self.dependants = ko.observableArray([]);
    self.newDependantName = ko.observable();
    self.newDobDD = ko.observable();
    self.readOnly = ko.observable();
    self.showEditButton = ko.observable();
    self.itemIndex = ko.observable();

    var i = 0;

    // Operations
    self.addDependant = function() {


        var data1 = {   itemIndex : (i),
                        dependantName : this.newDependantName(), 
                        dobDD : this.newDobDD(),
                        readOnly : "readonly",
                        showEditButton : (!0)
                        };
        self.dependants.push(data1);
        self.newDependantName("");
        self.newDobDD("");
        i++
    };
    self.removeDependant = function(dependant) { self.dependants.remove(dependant) };

    self.editDependant = function(i) {
        console.log("editedDependant");
        self.readOnly(undefined);
        self.showEditButton(!1)
    };
    self.saveDependantItem = function(self) {
        self.readOnly("readonly"), self.showEditButton(!0)
    };

}

ko.bindingHandlers.uniqueId = {

    init: function(element, valueAccessor) {
        var value = valueAccessor();
        value.id = value.id || ko.bindingHandlers.uniqueId.prefix + (++ko.bindingHandlers.uniqueId.counter);
        console.log("in handler");
        element.id = value.id;
    },
    counter: 0,
    prefix: "unique"
};


ko.bindingHandlers.uniqueFor = {
    init: function(element, valueAccessor) {
        var value = valueAccessor();
        value.id = value.id || ko.bindingHandlers.uniqueId.prefix + (++ko.bindingHandlers.uniqueId.counter);

        element.setAttribute("for", value.id);
    } 
};

ko.applyBindings(new DependantListViewModel());

1 个答案:

答案 0 :(得分:0)

该错误在您的init

中引用了这个问题
var value = valueAccessor(); // this is undefined
value.id = value.id // therefore this falls over

这就是问题所在:

self.dependants.push(data1);

应该是:

self.dependants.push(new Dependant(data1));

然后更新您的Dependant模型以传递索引:

this.itemIndex = ko.observable(data.itemIndex);

这是一个有效的Fiddle