我有一张只读电话号码表。电话号码有一个号码和一个类型(例如移动电话或家庭电话)。每个电话号码都有一个“编辑”按钮,单击该按钮后,您可以编辑电话号码并在模式对话框中键入。我将 Knockoutjs 用于只读表和编辑器。该表绑定到一个 observableArrayPhoneVMs
并且编辑器在单个PhoneVM
. 因为我希望用户在应用任何更改之前必须在模态上单击“确定”,所以模态在所选副本上工作PhoneVM
,当他们单击“确定”时,它会替换PhoneVM
表绑定到的 observableArray 中最初单击的. 这一切都很好。
现在我需要允许在与只读表相同的页面上编辑列表中的第一个电话(没有模式)。这个想法是为了在工作流程的早期更容易输入第一部电话。因此,您将在页面上输入您的手机,它会自动出现在下面的只读列表中,您也可以在模态中正常编辑它。我以为 Knockout 会让这件事变得简单,但我遇到了障碍。从这一点来看,只显示一个错误的例子会更容易。在这个小提琴中执行以下操作:https ://jsfiddle.net/ph4mhsof/
- 从文本框中编辑电话号码和标签。请注意所有电话列表中的第一部电话也会更新。
- 在下拉列表中更改电话类型。请注意,所有电话表中的类型 ID 和类型名称都发生了相应的变化。
- 单击删除第一部电话。第二部手机成为新的第一部手机。
- 从文本框中编辑电话号码和标签。请注意所有电话列表中的第一部电话按预期更新。
- 在下拉列表中更改电话类型。请注意所有电话列表中的类型 ID 更新。类型名称不会更新。
我正在使用自定义绑定将类型名称绑定到选择的文本。似乎该绑定的 init 函数中的 valueAccessor 必须专门指向原始的第一个 PhoneVM 的PhoneTypeName
属性,但我需要它做的是指向firstPhone
计算属性的PhoneTypeName
. 有没有什么办法解决这一问题?
原始jsfiddle的副本:
function phoneListVM() {
var _self = this;
this.phones = ko.observableArray([
new phoneVM(1, "Mobile", "123-234-3456"),
new phoneVM(2, "Home", "654-343-3211")
]);
this.firstPhone = ko.computed(function() {
return _self.phones()[0];
});
}
function phoneVM(typeID, typeName, Number) {
this.PhoneTypeID = ko.observable(typeID);
this.PhoneTypeName = ko.observable(typeName);
this.PhoneNumber1 = ko.observable(Number);
}
ko.bindingHandlers.selectedTextValue = {
init: function(element, valueAccessor) {
var value = valueAccessor();
$(element).change(function() {
value($("option:selected", this).text());
});
},
update: function(element, valueAccessor) {}
};
$(document).ready(function() {
var phoneList = new phoneListVM()
ko.applyBindings(phoneList);
$("button").click(function() {
phoneList.phones.shift();
});
});
.editor{
background-color:rgba(200,200,250, 0.2);
border: 1px solid rgba(0,0,0, 0.2);
padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h4>
Edit First Phone
</h4>
<div class="editor">
<p>Phone Number:
<input data-bind="value: firstPhone().PhoneNumber1" />
</p>
<p>Phone Type:
<select data-bind="value:firstPhone().PhoneTypeID, selectedTextValue:firstPhone().PhoneTypeName">
<option value="0"></option>
<option value="1">Mobile</option>
<option value="2">Home</option>
</select>
</p>
</div>
<h4>
All Phones
</h4>
<table>
<thead>
<tr>
<th>Type ID</th>
<th>Type Name</th>
<th>Number</th>
</tr>
</thead>
<tbody data-bind="foreach:phones">
<tr>
<td><span data-bind="text:PhoneTypeID"></span></td>
<td><span data-bind="text:PhoneTypeName"></span></td>
<td><span data-bind="text:PhoneNumber1"></span></td>
</tr>
</tbody>
</table>
<button type="button">
Remove First Phone
</button>