javascript - 在 Knockout.Js 中从 ajax JSON 响应绑定(bind)关联数组

标签 javascript ajax knockout.js

我在将 json 响应与 knockout.js 绑定(bind)时遇到问题。谁能帮我指出正确的方向。下面有两个版本的代码。版本 1 可以运行,但用户需要搜索。如果他们搜索多次,则会中断,因为绑定(bind)已经应用。

版本 1

var self = this;

self.Jobs = ko.observableArray();
self.Count = ko.observable();
self.Score = ko.observable();
self.Highlights = ko.observable();
self.Document = ko.observableArray();
self.id = ko.observable();
self.title = ko.observable();
self.description = ko.observable();
self.company = ko.observable();

self.error = ko.observable();


var jobsUri = '/home/search/';


function getAllJobs() {

    var search = $('#search').val();

    $.post(jobsUri, {
        search: search
    },

    function (data) {
        viewModel = {
        Jobs: data.Results,
        Count: data.Count,
        Document: Jobs.Document,
        id: Document.id,
        title: Document.title,
        description: Document.description,
        company: Document.company
        }
        ko.applyBindings(viewModel, $('#jobs').get(0));
    });

}

版本 2 似乎可以工作,元素出现在 DOM 中,但由于某种原因,我似乎无法通过 knockout 来访问元素以在前端显示。

版本 2

function ViewModel() {

    var self = this;

    self.data = ko.observableArray();

    getAllJobs();

}


function getAllJobs() {

    var self = this;

    self.Jobs = ko.observableArray([]);
    self.Count = ko.observable();
    self.Score = ko.observable();
    self.Highlights = ko.observable();
    self.Document = ko.observableArray();
    self.id = ko.observable();
    self.title = ko.observable();
    self.description = ko.observable();
    self.company = ko.observable();
    self.error = ko.observable();


    var jobsUri = '/home/search/';

    var search = $('#search').val();

    $.post(jobsUri, {
        search: search
    },

    function (data) {
        viewModel = {
            Jobs: data.Results,
            Count: data.Count,
            Document: Jobs.Document,
            id: Document.id,
            title: Document.title,
            description: Document.description,
            company: Document.company,

        }
    });

}


var viewModel = new ViewModel();
ko.applyBindings(viewModel);

html 是非常基础的。如前所述,它适用于上面的版本 1 代码,但不适用于版本 2!

<div class="row" id="jobs search">

    <input type="text" id="search" class="form-control" value="" placeholder='"Senior Manager" "Corporate Finance" London "Investment Banking"' />

     <input type="submit" class="typeahead search-submit btn btn-success btn-block " value="Search" onclick="getAllJobs();" />

    <hr />

    <div data-bind="foreach: Jobs">
        <div class="jobs-list">
            <h3 class="job-title" data-bind="text: Document.title"></h3>
            <p data-bind="text: Document.company"></p>
            <p data-bind="text: Document.description"></p>

        </div>
    </div>
</div>

我觉得我已经尝试了所有可能的方法,但就是没有破解它!非常感谢任何帮助。提前致谢

最佳答案

您的代码违反了 knockout 应用程序的基本原则: View 模型/ View 分离。

您的 View 模型中不应该有任何 DOM 交互或 jQuery 代码。 (除了 jQuery Ajax 调用,但您可以轻松地将它们替换为另一个 Ajax 库。事实上,除非您使用 jQuery UI 或具有显式 jQuery 依赖项的其他工具,否则请考虑在 knockout 应用程序中完全删除 jQuery。所有 DOM 操作都应该无论如何都要通过 knockout 来完成,只是为了方便 Ajax jQuery 有点太重了。)

如果您想访问 View 模型中的值(例如搜索词),请为其创建一个可观察对象,并通过 value 绑定(bind)将该可观察对象绑定(bind)到控件。

像这样:

function JobSearchForm() {
    var self = this;

    self.searchTerm = ko.observable();
    self.jobs = ko.observableArray();

    self.doSearch = function () {
        // todo: empty search term handling
        $.get('/home/search/', {
            search: self.searchTerm()
        }).done(function (data) {
            self.jobs(data.Results);
        });
    };
}

var viewModel = new JobSearchForm();
ko.applyBindings(viewModel);

对应 View :

<div class="row" id="jobs search">
    <input type="text" data-bind="value: searchTerm" class="form-control" placeholder='...' />
    <button data-bind="click: doSearch" class="typeahead search-submit btn btn-success btn-block">Search</button>
    <div data-bind="foreach: jobs">
        <div class="jobs-list" data-bind="with: Document">
            <h3 class="job-title" data-bind="text: title"></h3>
            <p data-bind="text: company"></p>
            <p data-bind="text: description"></p>
        </div>
    </div>
</div>

绑定(bind)是 View 模型和 View 交互的唯一地方。

由于我不知道您的服务器返回什么,我只能推测 foreach 绑定(bind)。如有疑问,您可以随时前来

<pre data-bind="text: ko.toJSON($data, null, 2)"></pre>

查看每次迭代中数据的可视化表示。或者您尝试Knockoutjs context debugger用于更高级调试的 Chrome 扩展。

关于javascript - 在 Knockout.Js 中从 ajax JSON 响应绑定(bind)关联数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41023175/

相关文章:

javascript - 尽管更改已注册,knockout.js 不会更新我的 foreach 绑定(bind)

checkbox - knockout JS :- Label bind with delete button

javascript - JS 窗口宽度/高度函数 - 有效但需要一些建议

javascript - 在多站点环境中使用 Service Worker API

javascript - 如何将 href 回显到可编辑 div

javascript - 如何在 Ionic/Angular 应用程序中使用 stripe.js

jquery - 在通过ajax提交之前使用jquery验证来验证表单

javascript - Ajax 无法获得成功功能。总是出错的函数。无法将数据发送到另一个文件

javascript - Ajax 负载使内容加倍

javascript - 如果从 Dropdown Knockout js 中选择特定值,则显示 div