【问题标题】:KnockoutJS - foreach not working with a single entry in viewmodelKnockoutJS - foreach 不能使用视图模型中的单个条目
【发布时间】:2015-12-12 08:24:42
【问题描述】:

我有以下代码,在成功的 AJAX 返回时,会显示一个带有地址列表的弹出窗口。淘汰版是2.3.0。

如果地址超过 1 个,则 html 会正确呈现“显示”字符串。

问题在于,如果只有 1 个地址,则 html 列表呈现但跨度中没有任何文本。

在这两种情况下,视图模型都正确地填充了数据,因此在我看来更新 html 时出现问题。

我已经尝试再次推送数据,虽然我可以使用 jQuery 来更新 html,但这并不能帮助我理解问题。

HTML

    <div id="reverseGeocodingResults">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title">Local Addresses</h4>
            </div>
            <div>
                <ul data-bind="foreach: vm.reverseGeocodingViewModel.AddressList" class="locationList">
                    <li class="locationListItem" data-bind="click: SubmitAddressRequest">
                        <div>
                            <span data-bind="text: Display"></span>
                        </div>
                    </li>
                </ul>
            </div>
        </div>
    </div>

Javascript(来自一个单独的文件,所以只取我认为相关的内容)

    var vm;
    var masterViewModel = function () {
        this.viewModel = { LocationList: ko.observableArray([]), SubQuery: ko.observable() };
        this.reverseGeocodingViewModel = { AddressList: ko.observableArray([]) };
    };

    function SubmitReverseGeocodingRequest(easting, northing, projectId, mouseLocation) {
        $.post('url?action=ReverseGeocodingLookup', {
            easting: easting,
            northing: northing,
            pid: projectId
        })
        .done(function (data) {
            spinner.stop();
            if (parseInt(data.NumberOfAddressesFound) > 0) {
                if (data.AddressList.length == 1) {
                    alert('just 1 address');
                }

                // remove all array items before adding new
                // Not pretty but gets around an issue the UI seems to have displaying the updated list
                if (vm.reverseGeocodingViewModel.AddressList().length > 0) {
                    vm.reverseGeocodingViewModel.AddressList.splice(0, vm.reverseGeocodingViewModel.AddressList().length);
                }

                vm.reverseGeocodingViewModel.AddressList(data.AddressList);
            }
        });
    )

    $(document).ready(function () {
        vm = new masterViewModel();
        ko.applyBindings(vm);
    })

HTML 结果 - 多个结果

    <ul class="locationList" data-bind="foreach: vm.reverseGeocodingViewModel.AddressList" style="height: 265px;">
        <li data-bind="click: SubmitAddressRequest" class="locationListItem">
            <div>
                <span data-bind="text: Display">Yates Wine Lodge, SWINDON</span>
            </div>
        </li>                        
        <li data-bind="click: SubmitAddressRequest" class="locationListItem">
            <div>
                <span data-bind="text: Display">The Brunel Centre, SWINDON</span>
            </div>
        </li>
    </ul>

HTML 结果 - 单个结果

    <ul class="locationList" data-bind="foreach: vm.reverseGeocodingViewModel.AddressList" style="height: 265px;">
        <li class="locationListItem" data-bind="click: SubmitAddressRequest">
            <div>
                <span data-bind="text: Display"></span>
            </div>
        </li>
    </ul>

我已经查看了有关此主题的各种先前问题,因此无法找到答案,但如果我错过了一个帖子,请指出我的另一篇文章。

【问题讨论】:

  • 您不需要splice 代码。如果您的绑定在显示列表时遇到问题,如果您不首先splice,那么您的代码似乎还有其他问题。此外,您的视图模型似乎并没有真正封装它应该包含的所有内容,但这是另一个讨论。但是,回到您的具体问题,我不确定是否可以仅使用您提供的信息来帮助您。您能否创建一个minimal, complete and verifiable 示例,最好还创建一个在 jsfiddle/jsbin/plunker 等网站上运行的示例?

标签: javascript jquery html knockout.js


【解决方案1】:
  1. 在添加新用途之前删除所有reverseGeocodingViewModel.AddressList.removeAll()
  2. 可能没找到,但你必须解析数据,$.parseJSON我用这个。
  3. 尝试使用

    $.each($.parsejSON(data), function(i, el){ reverseGeocodingViewModel.AddressList.push(el); })

希望对你有帮助

【讨论】:

    【解决方案2】:

    我注意到以下问题:

    • 函数SubmitReverseGeocodingRequest应该用}而不是)关闭
    • foreach: vm.reverseGeocodingViewModel.AddressList 应该是foreach: reverseGeocodingViewModel.AddressList,没有vm 因为vm 已经绑定了

      vm = new masterViewModel(); ko.applyBindings(vm);

    • 要清理AddressList,请使用vm.reverseGeocodingViewModel.AddressList([]) 而不是vm.reverseGeocodingViewModel.AddressList.splice(0, vm.reverseGeocodingViewModel.AddressList().length);

    注意:这里可能有错误

    <li class="locationListItem" data-bind="click: SubmitAddressRequest">
    

    所以AddressList 项目必须具有SubmitAddressRequest 功能。我不认为您使用该函数获取数据

    我已经根据你的代码创建了测试样本,看看here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-26
      • 1970-01-01
      • 2015-07-19
      • 2013-01-19
      • 2014-04-11
      • 2015-03-05
      • 2015-10-31
      相关资源
      最近更新 更多