KnockoutJS绑定未显示

时间:2014-07-04 09:02:42

标签: knockout.js

我使用Knockout JS和映射插件将MVC视图模型映射到viewmodel属性;

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。

知道我做错了吗?

1 个答案:

答案 0 :(得分: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将不再更新。

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

您可以使用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);
            },
        });
    };
}