简单的KnockoutJS绑定似乎不起作用

时间:2015-06-27 15:18:23

标签: javascript jquery html knockout.js

我的KnockoutJS脚本似乎有些错误,但我无法弄清楚它来自哪里。这是HTML代码:

    <h2>SendMessage</h2>

<div class="form-group" id="messageSender">
    <label>Select User Type</label>
    <select id="userType" data-bind="options: $parent.userTypes, optionsText: 'type', optionsValue: 'role'
            optionsCaption: 'Select a user type:', value: selectedUserType"></select><br/>
    <label>Select Reciepient</label>
    <select id="reciepient" data-bind="options: $parent.users, optionsText: 'fname', optionsValue: 'id', value: selectedUser, visible: userTypeSelected"></select>
    <br />
    <label>Message Text</label>
    <textarea data-bind="value:messageText, visible: userTypeSelected"></textarea><br/>
    <button data-bind="click:sendMessage">Send</button>
</div>

这是我的JavaScript代码:

$(document).ready(function () {


  var messageModel =   function Message(sender_id, reciever_id, messageText) {

        var self = this;

        self.sender_id = ko.observable(sender_id);
        self.reciever_id = ko.observable(reciever_id);
        self.messageText = ko.observable(messageText);
        self.mdate = Date.now();

        //send ajax request to the api  to add a send
        self.addMessage = function () {

            var dataObject = ko.toJSON(this);

            $.ajax({
                url: "/api/messageapi",
                type: 'add',
                data: dataObject,
                contentType: 'application/json',
                success: function (data) {
                    self.sender_id(null);
                    self.reciever_id(null);
                    self.messageText('');

                    alert("Message send successfully!");
                }
            });

        }


    }

var messageViewModel = function () {

        var self = this;

        self.userTypeSelected = ko.observable();
        //List of roles
        self.userTypes = [
           { role: 2, type: "Teacher" },
           { role: 3, type: "Parent" }
        ];

        self.messageText = ko.observable();
        self.users = function () {

            var role = this.userTypeSelected;
            if (role === 2) {
                $.ajax(
              {
                  url: "/api/MessageApi/GetTeachers/" + role,
                  type: 'get',
                  contentType: 'application/json',
                  success: function (data) {
                      return data;
                  },
                  fail: function () {
                      alert("Error occurred while sending data");
                  }
              });
            }


        };

        self.sendMessage = function () {
            alert("You clicked me!");//added this for testing whether the code works or not
        }

    }


    ko.applyBindings(new messageViewModel());
});

我在这里想要实现的是用户选择他/她想要发送消息的用户类型。选择用户类型后,通过Web Api(我使用asp.net mvc5)通过进行ajax调用从数据库中获取用户,并显示在下拉列表中。但是,当我运行代码时,事情似乎不起作用:

  • 第一个下拉列表不显示任何内容。但是,我已将其绑定到 userTypes 数组
  • 发送按钮不响应点击事件,即使我已将其绑定到 sendMessage 功能。
  • 第二个下拉列表的可见性由 userTypeSelected 值控制,但始终显示。

我的ajax调用中可能还有问题,但上面的问题是明显的问题

我在这里做错了什么?提前谢谢。

1 个答案:

答案 0 :(得分:2)

您的代码中存在很多错误

  1. 后,select中缺少逗号

    optionsValue:'role'

  2. 您不应在绑定中使用$parent,只需使用options: userTypesoptions: users中的属性名称

    <select id="userType" data-bind="options: userTypes, optionsText: 'type', optionsValue: 'role',
        optionsCaption: 'Select a user type:', value: selectedUserType"></select><br />
    <label>Select Reciepient</label>
    <select id="reciepient" data-bind="options: users, optionsText: 'fname', optionsValue: 'id', value: selectedUser, visible: userTypeSelected"></select>
    
  3. 在此部分的第一个selectvalue: selectedUserTypeselectedUserType属性不存在。您的意思是value: userTypeSelected吗?

    <select id="userType" data-bind="options: userTypes, optionsText: 'type', optionsValue: 'role',
        optionsCaption: 'Select a user type:', value: userTypeSelected">
    
  4. 您在viewModel中缺少self.selectedUser = ko.observable();

  5. 你的var messageModel = function Message(...)似乎完全没有意义,因为没有在任何地方引用。

  6. self.users = function()...不会以这种方式运作。您需要的是在第一个选择中的change事件中设置一个函数来调用$ .ajax来加载self.users = ko.observableArray()

    • self.users = function()...替换为self.users = ko.observableArray()

    • 向viewModel添加self.userTypeChanged函数,该函数将调用$ .ajax并将结果填充给用户observableArray。

      • 您在var role = self.userTypeSelected();
      • 之后缺少一对()
      • success回调中,您需要填写users observableArray:self.users(data);
  7. 这应该是self.userTypeChanged函数

        self.userTypeChanged = function () {
            var role = self.userTypeSelected();
            if (role === 2) {
                $.ajax({
                    url: "/api/MessageApi/GetTeachers/" + role,
                    type: 'get',
                    contentType: 'application/json',
                    success: function (data) {
                        self.users(data);
                    },
                    fail: function () {
                        alert("Error occurred while sending data");
                    }
                });
            }
        };
    
    1. change事件添加到第一个选择中以致电userTypeChanged

      <select id="userType" data-bind="options: userTypes, optionsText: 'type', optionsValue: 'role',
          optionsCaption: 'Select a user type:', value: userTypeSelected, event: { change : userTypeChanged }"></select>
      
    2. 这是完整的代码。我希望这有帮助

      HTML

      <h2>SendMessage</h2>
      
      <div class="form-group" id="messageSender">
          <label>Select User Type</label>
          <select id="userType" data-bind="options: userTypes, optionsText: 'type', optionsValue: 'role',
              optionsCaption: 'Select a user type:', value: userTypeSelected, event: { change : userTypeChanged }"></select><br />
          <label>Select Reciepient</label>
          <select id="reciepient" data-bind="options: users, optionsText: 'fname', optionsValue: 'id', value: selectedUser, visible: userTypeSelected"></select>
          <br />
          <label>Message Text</label>
          <textarea data-bind="value:messageText, visible: userTypeSelected"></textarea><br />
          <button data-bind="click:sendMessage">Send</button>
      </div>
      

      JS

          $(document).ready(function () {
              var messageViewModel = function () {
      
                  var self = this;
                  self.selectedUser = ko.observable();
                  self.userTypeSelected = ko.observable();
                  //List of roles
                  self.userTypes = [
                      { role: 2, type: "Teacher" },
                      { role: 3, type: "Parent" }
                  ];
      
                  self.messageText = ko.observable();
      
                  self.users = ko.observableArray();
      
                  self.userTypeChanged = function () {
                      var role = self.userTypeSelected();
                      if (role === 2) {
                          $.ajax(
                          {
                              url: "/api/MessageApi/GetTeachers/" + role,
                              type: 'get',
                              contentType: 'application/json',
                              success: function (data) {
                                  self.users(data);
                              },
                              fail: function () {
                                  alert("Error occurred while sending data");
                              }
                          });
                      }
                  };
      
                  self.sendMessage = function () {
                      alert("You clicked me!");//added this for testing whether the code works or not
                  }
              }
      
              ko.applyBindings(new messageViewModel());
          });