【问题标题】:observable not defined inside object literal knockout可观察对象未在对象字面量剔除中定义
【发布时间】:2012-12-09 03:52:08
【问题描述】:

我在淘汰视图模型的对象文字中定义了一个可观察对象。现在,当我运行应用程序时,它无法访问 observable 。

$(function () {
  var viewModel =    {
    Folders: ['Inbox', 'Archive', 'Sent', 'Spam'],
    Title: ko.observable("My View Model Test"),
    SelectedFolder: ko.observable(),
    Mails: ko.observableArray(),
    SelectedMail: ko.observable(),
    SelectedChoices: ko.observable(false),


    navigate: function (folder) {           
        SelectedFolder(folder);
        $.ajax({
            url: "/Api/MailBox",
            data: { folder: folder },
            success: function (data) {
                self.Mails(data);
            },
            statusCode: {
                404: function () {
                    console.log("No Mails");
                }
            }

        });
    }
};
}

当我将点击事件绑定到 navigate 函数时。它说 SelectedFolder 是 undefined 。有人可以告诉我为什么它无法访问 navigate 函数中的 SelectedFolder observable 吗?

【问题讨论】:

    标签: knockout.js knockout-2.0


    【解决方案1】:

    当 navigate 方法运行并寻找 SelectedFolder observable 时,它​​首先在 navigate 方法的上下文中寻找它。否则,它会跳转到父上下文,这是页面准备就绪时正在运行的匿名函数。如果失败,它会跳转到全局上下文 - 它在那里找不到 SelectedFolder,所以它放弃了。

    要解决此问题,请更改您的导航方法以引用在页面准备好时运行的匿名函数的上下文中可用的 viewModel 变量:

    navigate: function (folder) {           
      viewModel.SelectedFolder(folder);
      $.ajax({
        url: "/Api/MailBox",
        data: { folder: folder },
        success: function (data) {
          viewModel.Mails(data);
        },
        ...
    

    请注意,我还在成功回调中添加了对 viewModel 的引用,以便它可以找到 Mails observable。

    这应该可行,但是,我建议您考虑更改您的结构,以便您的导航方法不依赖于特定的全局变量。这是一种方法:

    var myViewModel = function() {
        var self = this;
        self.Folders = ['Inbox', 'Archive', 'Sent', 'Spam'];
        self.Title = ko.observable("My View Model Test");
        self.SelectedFolder = ko.observable();
        self.Mails = ko.observableArray();
        self.SelectedMail = ko.observable();
        self.SelectedChoices = ko.observable(false);
    
        self.navigate = function (folder) {           
            self.SelectedFolder(folder);
            $.ajax({
                url: "/Api/MailBox",
                data: { folder: folder },
                success: function (data) {
                    self.Mails(data);
                },
                statusCode: {
                    404: function () {
                        console.log("No Mails");
                    }
                }
    
            });
        };
    };
    
    $(function () {
      var ViewModel = new myViewModel();
      ko.applyBindings(viewModel);
    });
    

    【讨论】:

      【解决方案2】:

      问题可能是调用该方法时的当前上下文。如果该方法被单击事件调用,则this 可能是单击事件绑定到的对象,因此它会尝试在该元素上查找 SelectedFolder 方法。

      不确定这是否是最好的方法,但这是一种可能的解决方案:

      var viewModel =    {
        Folders: ['Inbox', 'Archive', 'Sent', 'Spam'],
        Title: ko.observable("My View Model Test"),
        SelectedFolder: ko.observable(),
        Mails: ko.observableArray(),
        SelectedMail: ko.observable(),
        SelectedChoices: ko.observable(false)
      };
      
      viewModel.navigate = function (folder) {           
        viewModel.SelectedFolder(folder);
        $.ajax({
          url: "/Api/MailBox",
          data: { folder: folder },
          success: function (data) {
            viewModel.Mails(data);
          },
          statusCode: {
            404: function () {
              console.log("No Mails");
            }
          }
      });
      

      【讨论】:

      • 您的想法是正确的,但问题是我想将方法​​移动到对象文字中。您所做的超出了 object literal 的范围。那么是不是可以在对象字面量中定义函数呢?
      猜你喜欢
      • 1970-01-01
      • 2014-10-23
      • 2016-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多