observable not defined inside object literal knockout

瘦欲@ 提交于 2019-12-24 07:37:17

问题


I have a observable defined inside a object literal of a knockout viewmodel . Now when I ran the application .Its unable to access the 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");
                }
            }

        });
    }
};
}

when I have bind the click event to navigate function . It says SelectedFolder is undefined . Can someone tell me why is it unable to access the SelectedFolder observable inside the navigate function ?


回答1:


When the navigate method is running and it looks for the SelectedFolder observable, it first looks for it in the context of the navigate method. Failing that, it jumps up to the parent context, which is the anonymous function being run when the page is ready. Failing that, it jumps to the global context - it can't find SelectedFolder there, so it then gives up.

To fix this, change your navigate method to reference the viewModel variable that is available in the context of the anonymous function being run when the page is ready:

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

Note that I also added a reference to the viewModel in the success callback so that it could find the Mails observable.

This should work, however, I would recommend considering changing your structure so that your navigate method isn't dependent on specific global variables. Here is one way:

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:


The issue is probably what the current context is when the method is called. If the method is being called by a click event then this is probably the object which the click event was bound to, and so it tries to find a SelectedFolder method on that element.

Not sure if this is the best way, but here is one possible solution:

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");
      }
    }
});


来源:https://stackoverflow.com/questions/13992298/observable-not-defined-inside-object-literal-knockout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!