使绑定元素在初始页面加载后填充时显示

Make bound element appear when populated after initial page load

本文关键字:加载 填充 显示 元素 绑定      更新时间:2023-09-26

在链接的 JS Fiddle 中,我有一个包含 2 个联系人对象的列表,以及页面加载时的空active_contact对象。 单击联系人列表下的"激活"链接时,我希望该联系人的属性填充活动联系人输入字段。 目前,我填充active_contact对象的函数正在触发,并且值按预期填充,但它没有显示在页面上(检查元素时,输入字段甚至不会显示在代码中)。

值得一提的是,这是我第一次使用Knockout,所以我完全有可能错过了一些非常基本的东西。

代码:

.HTML

var initialData = [
    { firstName: "Danny", lastName: "LaRusso", phones: [
        { type: "Mobile", number: "(555) 121-2121" },
        { type: "Home", number: "(555) 123-4567"}]
    },
    { firstName: "Sensei", lastName: "Miyagi", phones: [
        { type: "Mobile", number: "(555) 444-2222" },
        { type: "Home", number: "(555) 999-1212"}]
    }
];
 
var ContactsModel = function(contacts) {
    var self = this;
    self.contacts = ko.observableArray(ko.utils.arrayMap(contacts, function(contact) {
        return { firstName: contact.firstName, lastName: contact.lastName, phones: ko.observableArray(contact.phones) };
    }));
    
    self.active_contact = ko.observable();
 
    self.makeActive = function(firstName){
        for(var i in self.contacts()){
			if(self.contacts()[i].firstName == this.firstName){
                console.log(self.contacts()[i]);
				 self.active_contact = self.contacts()[i];
			}
		}
    }
 
};
 
ko.applyBindings(new ContactsModel(initialData));
 
   <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class='liveExample'> 
    <h2>Contacts</h2>
    <div id='contactsList'>
        <h3>active contact: </h3>
        <div class="active" data-bind="with: active_contact">
            <input type="text" data-bind="value: firstName" />
            <input type="text" data-bind="value: lastName" />
        </div>
        <table class='contactsEditor'>
            <tr>
                <th>First name</th>
                <th>Last name</th>
                <th>Phone numbers</th>
            </tr>
            <tbody data-bind="foreach: contacts">
                <tr>
                    <td>
                        <input data-bind='value: firstName' />
                        <div><a href='#' data-bind='click: $root.makeActive'>Make Active</a></div>
                    </td>
                    <td><input data-bind='value: lastName' /></td>
                    <td>
                        <table>
                            <tbody data-bind="foreach: phones">
                                <tr>
                                    <td><input data-bind='value: type' /></td>
                                    <td><input data-bind='value: number' /></td>
                                </tr>
                            </tbody>
                        </table>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</div>

self.makeActive有两个问题:

.makeActive 没有收到firstname ,它确实接收了完整的contact对象 - 所以整个for循环是不必要的,因为你已经有了你要找的东西。

主要问题出在这一行上:

self.active_contact = self.contacts()[i];

您不是在为可观察量分配新值,而是在替换可观察量本身。这就是为什么你的标记不再更新 - 它最初绑定到的可观察量现在已经消失了。

试试这个:

self.makeActive = function (contact) {
  self.active_contact(contact);
};

试试这个: http://jsfiddle.net/dsqo3mnw/

首先,我更改了这个:

self.active_contact = self.contacts()[i];

对此:

var activeContact = self.contacts()[i];
self.active_contact(activeContact.firstName + " " + activeContact.lastName);

我也是敲除的新手,但这是我的理解:active_contact不是一个字符串对象;它是一个可观察的函数。若要更改其值,必须调用该函数并传入新值。

其次,我从这里更改了您的数据绑定:

<div class="active" data-bind="with: active_contact">
    <div data-bind="text: firstName"></div>
</div>

对此:

<p style="font-weight: bold">
    Modified Active Contact Binding: 
    <span data-bind="text: active_contact"></span>
</p>

我还不熟悉with绑定,但text绑定应该可以满足您的需求,不是吗?