<小时/>I am having problems with route.html's
foreach
binding in the project Flight Management Computer.
问题1:value
绑定(bind)于 observableArray
所有同时更新
对于javascript中的路由,我设置了ko.observableArray
的Array
的ko.observable
(听起来很令人困惑,但下面仍然附有代码):
/* All bindings applied to viewmodel already */
var route = ko.observableArray();
var DEFAULT_ROUTE = [
ko.observable(), // Waypoint Name
ko.observable(), // Lat.
ko.observable(), // Lon.
ko.observable(), // Altitude Restriction
ko.observable(false), // Waypoint isValid
ko.observable('') // Waypoint information
];
单击特定按钮会添加 DEFAULT_ROUTE
没有问题,正如它所说的
route.push(DEFAULT_ROUTE);
HTML 代码大致如下所示,并且没有 UI 问题:
<tbody data-bind="foreach: route">
<tr class="wpt-row">
<td><input data-bind="value: $data[0]"></td> <!--waypoint input-->
<td><input data-bind="value: $data[1]"></td> <!--lat. input-->
<td><input data-bind="value: $data[2]"></td> <!--lon. input-->
<td><input data-bind="value: $data[3]"></td> <!--alt. input-->
</tr>
</tbody>
但是,当外部ko.observableArray
中有多个数组时,就会出现问题。 ,因为在 UI 和 JavaScript 中更改一个输入值都会更新每个数组中的所有值。示例:
var route = ko.observableArray([DEFAULT_ROUTE, DEFAULT_ROUTE, DEFAULT_ROUTE]);
// Then, outside viewmodel (in javascript console)
route()[0][0]('WPT'); // Sets the waypoint of the first input field to be 'WPT'
// Later
route()[0][0](); // 'WPT', correct
route()[1][0](); // 'WPT', incorrect, should be undefined
route()[2][0](); // 'WPT', incorrect, should be undefined
我设置了类似的foreach
在不同的文件中,但带有 <input>
就像 <span>
,和data-bind
如text: $data[x]
而不是value
。那个不同的文件工作正常,没有任何问题。不同的文件是 log.html
问题 2(或者更确切地说,一个问题)
在route
之后问题已解决,我希望当同一数组中的另一个值发生更改时更新单个数组(一个航路点输入字段)中的某些特定值。即:
// Scenario 1, waypoint is a valid waypoint with proper coords
var waypoint = 'WAATR';
var coords = getWaypoint(waypoint); // [42.1234, -70.9876]
route()[0][0](waypoint);
// route()[0][0]() is now 'WAATR'
// route()[0][1] and route()[0][2] should automatically update with value `coords[0]` and `coords[1]`
// route()[0][4] should be set to true (valid waypoint)
// Scenario 2, waypoint is NOT a valid waypoint
var waypoint = 'IDK';
var coords = getWaypoint(waypoint); // []
route()[0][0](waypoint);
// route()[0][0]() is now 'IDK'
// route()[0][1] and route()[0][2] should remain undefined, waiting for users to manually input coordinates
// route()[0][4] should be false (invalid waypoint)
我阅读了文档,其中有一个 extend
功能,但我不太明白。现在的挑战是如何将这些自动填充功能限制为特定数组(航点输入字段),而不是(如问题#1)整个输入数据表。
如果有人能提供帮助,我将不胜感激,因为 route
是整个项目最重要的特点。
最佳答案
您确实应该使用对象而不是数组。它使一切变得更容易阅读和理解,并且极大地帮助调试。
var Route = function() {
this.waypointName = ko.observable();
this.lat = ko.observable();
this.lon = ko.observable();
this.altitudeRestriction = ko.observable();
this.isValid = ko.observable(false);
this.waypointInfo = ko.observable('');
};
就像您已经想到的那样,您现在可以通过调用 new Route()
来使用它。您将解决问题 1 并拥有更易于阅读和维护的代码。解决问题 2 的正确基础:
因为您现在有了一个明确定义的模型,所以您可以开始使用 subscribe
或 compulated
定义属性之间的关系。您想要更改 waypointName
属性并让其他属性自动更新:
var Route = function() {
this.waypointName = ko.observable();
// Automatically updates when you set a new waypoint name
var coords = ko.pureComputed(function() {
return getWaypoint(this.waypointName());
}, this);
// Check if we got correct coords
this.isValid = ko.pureComputed(function() {
return coords().length === 2;
}, this);
// Auto-extract lat from coords, null if invalid
this.lat = ko.pureComputed(function() {
return this.isValid()
? coords()[0]
: null;
}, this);
// Auto-extract lat from coords, null if invalid
this.lon = ko.pureComputed(function() {
return this.isValid()
? coords()[1]
: null;
}, this);
};
您现在拥有一条默认Route
,其中包含isValid: false
、lat: null
、lon:null
和当您将 waypointName
设置为字符串值(例如 route.waypointName("WAATR")
)时,所有属性都会自动更新。
关于javascript - knockout : observableArray of arrays of observable inputs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45272302/