【问题标题】:Knockout update variable in ObservableArrayObservableArray 中的淘汰赛更新变量
【发布时间】:2013-08-22 16:44:30
【问题描述】:

我正在用 HTML5、JavaScript 和 CSS 编写一个移动应用程序,并使用 PhoneGap 将其转换为一个应用程序。我有一个位置列表、一些其他数据以及用户与每个位置的距离。 我有一个淘汰赛 observableArray,其中填充了具有以下格式的 json 信息。

[{
   "Id":1,
   "Name":"Field 1",
   "Available":12,
   "InUse":5
}]

我是,然后使用 GeoLocation 查找用户的当前位置,并确定他或她与每个位置的距离。我正在使用此代码监视用户的位置。

navigator.geolocation.watchPosition(showPosition, showError, options)

。当他们走近其中一个字段时,我希望能够在每个字段发生变化时显示他们与每个字段的距离。我的 HTML 很简单,看起来像这样:

<table style="width: 95%; padding: 2px; margin-left: 2px;">
            <thead>
                <tr style="text-align: left">
                    <th>Field</th>
                    <th>Available</th>
                    <th>In Use</th>
                    <th>Distance</th>
                </tr>
            </thead>

            <tbody data-bind="foreach: myArray" >
                <tr>
                    <td><span data-bind="text: Field"></span></td>
                    <td><span data-bind="text: Available"></span></td>
                    <td><span data-bind="text: InUse"></span></td>
                    <td><span data-bind="text: Proximity"> </span> </td>
                </tr>
            </tbody>
    </table>    

一切正常,当我走动时正在调用“showPosition”,但我不知道如何更新 observableArray 中的邻近字段,因为它发生了变化。

我的 showPosition 方法(同事写的)是这样的。

function showPosition(position) {
        for (i = 0; i < config.geoLocs.length; i++) {
            var distance =
                calculateDistance(position.coords.latitude,
                                  position.coords.longitude,
                                  config.geoLocs[i].Lat,
                                  config.geoLocs[i].Lng)

            config.geoLocs[i].Proximity = (distance * 1000).toFixed(0) + " m";

        }

    }

我知道我的 observableArray 只会在它发生变化时更新,即插入或删除一个新对象,如果其中的项目被更新,则不会更新。我是否必须为每个对象创建一个可观察对象,然后将其推送到数组中,或者是我的“showPosition”方法中的一种简单方法,我可以轻松地遍历数组并更新每个“poximity”字段?

我希望所有这些都有意义?

注意:showPosition() 方法在编写时并未考虑淘汰绑定。我的同事计划使用 JavaScript 在表中查找每个并手动更新它。

【问题讨论】:

  • 我想我已经成功了。我所做的只是在 showPosition() 方法中清除 observableArray 然后读取它。例如我的数组(“”); myArray(config.geoLocs);

标签: knockout.js


【解决方案1】:

我知道我的 observableArray 只会在它发生变化时更新,即插入或删除一个新对象,并且如果其中的项目被更新则不会更新

这是真的……在某种程度上。但是,如果您正确映射了 JSON,那么 数组中的项目 也将是可观察的。如果不是这种情况,您应该尝试更改它,因为以下解决方案可能比您在评论中发布的解决方案更好(清除 myArray 并重新添加所有项目)。

这是更新后的showPosition 的样子:

// Assuming your view model is available like this in scope:
var viewModel = however_it_was_constructed;

function showPosition(position) {
    var items = viewModel.myArray();

    for (i = 0; i < items.length; i++) {
        var distance =
            calculateDistance(position.coords.latitude,
                              position.coords.longitude,
                              items[i].Lat,
                              items[i].Lng)

        var newProximity = (distance * 1000).toFixed(0) + " m";

        // Update the observable, so the view gets updated automatically
        items[i].Proximity(newProximity);
    }
}

同样,这只适用于myArray 中的属性是可观察的。但是,根据您的问题,我觉得它们应该是,因为您希望 View 观察属性的变化。

【讨论】:

  • 感谢 Jeroen 抽出宝贵时间。你说的很有道理。 ATM 数组中的项目是不可观察的,所以这不起作用。在适当的时候,我会修改代码,然后尝试你应该可行的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-13
  • 1970-01-01
  • 1970-01-01
  • 2013-05-17
  • 1970-01-01
相关资源
最近更新 更多