【问题标题】:KnockoutJS bindings not showingKnockoutJS 绑定未显示
【发布时间】:2014-07-04 09:02:42
【问题描述】:

我正在使用带有映射插件的 Knockout JS 将 MVC 视图模型映射到视图模型属性;

var viewModel = function() {
    var self = this;
    self.EntityKey = 0;
    self.observables = ko.observable();
    self.RoleName = ko.observable("");

    // CRUD Actions
    self.getPaged = function (page) {
        $.ajax({
            url: "/Core/Authentication/Role/UpdateIndex",
            dataType: 'json',
            data: { pageNumber: page },
            success: function (result) {
                self.observables = ko.mapping.fromJS(result);
            },
        });
    };

    this.remove = function (data) {
        $.ajax({
            type: "POST",
            url: "/Core/Authentication/Role/Delete",
            dataType: 'json',
            data: { userId: data.EntityKey() },
            success: function (result) {
                self.getPaged(self.observables.CurrentPage);
                toastr.success(result);
            },
        });
    };

    this.update = function (data) {
        $.ajax({
            type: "POST",
            url: "/Core/Authentication/Role/Update",
            dataType: 'json',
            data: ko.toJSON(this),
            success: function (result) {
                toastr.success(result);
            },
        });
    };

    this.create = function () {
        $.ajax({
            type: "POST",
            url: "/Core/Authentication/Role/Create",
            dataType: 'json',
            data: ko.toJSON(this),
            success: function (result) {
                self.getPaged(self.observables.CurrentPage);
                toastr.success(result);
                self.RoleName("");
            },
        });
    };

    self.getPaged(1);                      
}

$(function () {
    var vm = new viewModel();
    ko.applyBindings(vm);
});

这是我的观点;

<table data-bind="visible: observables.PageItems">
    <tr>
        <th>@AuthRes.Resource.EntityKey</th>
        <th>@AuthRes.Resource.RoleName</th>
        <th>@AuthRes.Resource.Update</th>
        <th>@AuthRes.Resource.Delete</th>
    </tr>
    <tr data-bind="foreach: observables.PageItems">
        <td><span data-bind="text: $data.EntityKey" /></td>
        <td><input type="text" data-bind="value: $data.RoleName" /></td>
        <td><a data-bind="click: $root.update.bind($data)">@AuthRes.Resource.Update</a></td>
        <td><a href='#' data-bind="click: $root.remove.bind($data)">@AuthRes.Resource.Delete</a></td>
    </tr>
</table>

<h2>@AuthRes.Resource.CreateNew</h2>
<table>
    <tr>
        <th>@AuthRes.Resource.RoleName</th>
        <th></th>
    </tr>
    <tr>
        <td>
            <input type="text" required="required" data-bind="value: RoleName" />
        </td>
        <td>
            <a href="#" data-bind="click: $root.create" />@AuthRes.Resource.Submit</a>
        </td>
    </tr>
</table>

viewModel.observables 更新正确,数据正确,但由于某种原因没有绑定到 observables.PageItems 的 foreach。

知道我做错了什么吗?

【问题讨论】:

    标签: knockout.js


    【解决方案1】:

    1. foreach 将应用于您的标签的子标签。

    使用您的代码

    <tr data-bind="foreach: observables.PageItems">
        <td><span data-bind="text: $data.EntityKey" /></td>
        <td><input type="text" data-bind="value: $data.RoleName" /></td>
        <td>
          <a data-bind="click: $root.update.bind($data)">@AuthRes.Resource.Update</a>
        </td>
        <td>
         <a href='#' 
            data-bind="click: $root.remove.bind($data)">@AuthRes.Resource.Delete</a>
         </td>
    </tr>
    

    只会创建一个tr

    尝试使用无容器语法:

    <!-- ko foreach: observables.PageItems -->
    <tr>
        <td><span data-bind="text: $data.EntityKey" /></td>
        <td><input type="text" data-bind="value: $data.RoleName" /></td>
        <td>
          <a data-bind="click: $root.update.bind($data)">@AuthRes.Resource.Update</a>
        </td>
        <td>
         <a href='#' 
            data-bind="click: $root.remove.bind($data)">@AuthRes.Resource.Delete</a>
         </td>
    </tr>
    <!-- /ko -->
    

    2.另外,为了检查visible 绑定,您可能想尝试

    <table data-bind="visible: observables.PageItems().length > 0">
    

    3.您的映射语法不正确

    当您声明self.observables = ko.observable(); 并绑定到它时,knockout 将创建一个链接,以便当您更新self.observables 时,html 将更新。

    现在当你这样做self.observables = ko.mapping.fromJS(result); 时,它不会更新,它会断开链接并分配一个新的 observable。这意味着 html 将不再更新。

    如果您在绑定 (ko.applyBindings) 之前执行此语法 self.observables = ko.mapping.fromJS(result); 是正确的,但您还没有数据。

    您可以做的是使用if 绑定来检查您的数据是否已加载。这将防止在不满足 if 条件时创建绑定链接(每次条件更改为 true 时都会重新创建绑定)。这样您的绑定就不会中断。

    <!-- ko if: hasInit -->
    <table data-bind="visible: observables.PageItems">
        <!-- ... -->
    </table>
    <!-- /ko --->
    

    还有js

    var viewModel = function() {
        var self = this;
        self.EntityKey = 0;
        self.hasInit = ko.observable(false);
        //self.observables = ko.observable(); //REMOVE THIS LINE, 
                                              //observables will be created after
        self.RoleName = ko.observable("");
    
        // CRUD Actions
        self.getPaged = function (page) {
            $.ajax({
                url: "/Core/Authentication/Role/UpdateIndex",
                dataType: 'json',
                data: { pageNumber: page },
                success: function (result) {
                    if (typeof self.observables === 'undefined') { //first call
                        self.observables = ko.mapping.fromJS(result);
                         self.hasInit(true);
                   } else //updates
                        ko.mapping.fromJS(results, self.observables);
                },
            });
        };
    }
    

    【讨论】:

    • 虽然这会有所帮助,但不幸的是它并不能解决我的问题。尽管 PageItems 包含数据,但整个表仍处于隐藏状态。
    • 我进行了更改,但表格仍未显示。数据肯定在更新,我有一个警报,目前有 15 条记录。
    • 确实比这更复杂,我会更新
    • 你不应该输入这个,你是否在正确的地方设置了if绑定?我忘了更新 hasInit 到,会更正
    • !!!!对不起,我把 Init 放在了错误的 html 页面上!我已经做到了,现在可以了,你是我的英雄!
    猜你喜欢
    • 2012-10-12
    • 2012-07-18
    • 1970-01-01
    • 1970-01-01
    • 2016-01-24
    • 1970-01-01
    • 1970-01-01
    • 2015-05-27
    • 1970-01-01
    相关资源
    最近更新 更多