KnockoutJS - 使用内部函数更新对象

时间:2013-02-26 21:15:10

标签: javascript jquery ajax knockout.js

我有一个“这个”问题,并希望得到任何帮助

这是我的基本代码

function xxx(val)
{
   this.x = val;
   this.change = function() {
     var self = this;
     $.ajax({
         blah: '',
         blah: '',
         success: function(data) { self.x = 5; },
     });
   };
}

var newX = new x(1);
newX.change();

console.log(newX.x);

希望这是有道理的,

我要做的是更新jquery ajax响应中的原始对象。我没有访问'this'所以我试图将它传递给'self'变量,但即使代码按预期运行,对象值似乎也没有更新。

我确信有一个简单的答案,我只是不知道。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:3)

因此,解决此问题的方法是查看函数声明。每个函数声明都会为您提供一个新的this对象。将您感兴趣的人存放在正确的位置。如果我是正确的,看起来你真的想要访问原始xxx函数范围的范围。因此,不要将this存储在change函数中,而是将其存储在原始范围内。像这样:

function xxx(val)
{
   var self = this;

   this.x = val;

   this.change = function() {
     var that = this;
     $.ajax({
         blah: '',
         blah: '',
         success: function(data) { self.x = 5; },
     });
   };
}

var newX = new x(1);
newX.change();

console.log(newX.x);

这里的另一个问题是你正在使用AJAX来进行调用,因此你需要一个Deferred对象,或者你可以在适当的时间为该函数添加一个回调,如下所示:

   function xxx(val)
        {
           var self = this;

           this.x = val;

           this.change = function(callback) {
             var that = this;
             $.ajax({
                 blah: '',
                 blah: '',
                 success: function(data) { 
                      self.x = 5;
                      if (typeof callback === "function"){
                            callback.call(this);
                      }
                 }
             });
           };
        }


    var newX = new xxx(1);

    newX.change(function(){
        console.log(newX.x);
    });

答案 1 :(得分:2)

淘汰赛......你必须做那样的事情:

function Xxx(val)
{
   var self = this;

   this.x = ko.observable(val);

   this.change = function() {
     // "that" may be different to "self" in some
     // cases...
     var that = this;
     $.ajax({
         url: '...',
         type: 'get',
         success: function(data) {
             self.x(5);
         },
         error: function(a) {
             console.log('got an error');
         }
     });
   };
}

var newX = new Xxx(1);
newX.change();

ko.computed(function () {
    // This will get called everytime
    // newX.x is changed
    console.log(newX.x());
});

当您创建可能发生变化的变量时,您必须将其创建为可观察变量。事实上,observable是你调用的函数。当被调用时,它将更新其内部值,并且它还将在“观察”observable的任何地方触发任何更改

绝不应该尝试this.x = 5。它将覆盖实际的可观察对象,因此它永远不会触发每个观察者的变化。

修改

如果您有兴趣了解计算的工作原理。计算变量是listen到可观察量的函数。创建computed时,将调用一次以检查从其中调用的可观察对象。这是一种“跟踪”依赖关系的方法。在此示例中,您应该至少看到两个控制台日志。一个用1,然后用5.

就我而言,计算变量是一种匿名的,因为它不受任何影响。在某些情况下,您可能需要观察一个变量但使用多个observable。防止更新任何其他已使用的observable。有一些方法可以做到这一点。您可以在“观察”所需的可观测量后返回。

或者您可以创建一个子函数,该函数将在使用setTimeout(..., 0);计算后稍微触发。有几种方法可以实现一些非常好的技巧。

相关问题