2014-04-25 111 views
4

嗯,这不是最好的情况说明...无论如何,我试图更新我的视图模型,但它不工作。默认情况下,我从控制器功能,并通过点击按钮获取数据 - 从同位指示其他功能,但视图模型只包含第一视图模型初始化后接收到的数据。Knockout.js更新视图模型上的按钮点击

<script> 
    function viewModel() { 
     var self = this; 
     self.currentPage = ko.observable(); 
     self.pageSize = ko.observable(10); 
     self.currentPageIndex = ko.observable(0); 
     self.salesdata = ko.observableArray(); 
     self.newdata = ko.observable(); 
     self.currentPage = ko.computed(function() { 
      var pagesize = parseInt(self.pageSize(), 10), 
      startIndex = pagesize * self.currentPageIndex(), 
      endIndex = startIndex + pagesize; 
      return self.salesdata.slice(startIndex, endIndex); 
     }); 
     self.nextPage = function() { 
      if (((self.currentPageIndex() + 1) * self.pageSize()) < self.salesdata().length) { 
       self.currentPageIndex(self.currentPageIndex() + 1); 
      } 
      else { 
       self.currentPageIndex(0); 
      } 
     } 
     self.previousPage = function() { 
      if (self.currentPageIndex() > 0) { 
       self.currentPageIndex(self.currentPageIndex() - 1); 
      } 
      else { 
       self.currentPageIndex((Math.ceil(self.salesdata().length/self.pageSize())) - 1); 
      } 
     } 
     //Here I'm trying to update ViewModel 
     self.request = function (uri) { 
      $.ajax({ 
       url: uri, 
       contentType: 'application/json', 
       data: [], 
       type: 'GET', 
       cache: false, 
      success: function (data) { 
       ko.mapping.fromJS(data.$values, {}, self.salesdata); 
      } 
      }); 
     } 
    } 
    $(document).ready(function() { 
     $.ajax({ 
      url: "/api/sales", 
      type: "GET", 
      cache: false, 
     }).done(function (data) { 
      var vm = new viewModel(); 
      vm.salesdata(data.$values); 
      ko.applyBindings(vm); 
     }).error(function (xhr, status, error) { 
      var err = eval("(" + xhr.responseText + ")"); 
      alert(err.Message); 
     }); 
     //Here i'm calling for ViewModel update 
     $(".btn-default").click(function() { 
      days = $(this).val(); 
      var uri = "/api/sales?days=" + days;  
      new viewModel().request(uri); 
     }); 
    }); 
</script> 

UPDATE。 我chaged的代码块中我得到新数据如下:

self.request = function (uri) { 
       $.getJSON(uri, function (data) { 
        ko.mapping.fromJS(data.$values, {}, viewModel); 
       }); 
      } 

不幸的是这是行不通的为好。这里没有任何JS错误,控制器返回更新数据的适当部分。

+0

您确定没有JavaScript错误,并且您的请求调用成功处理程序吗? – milagvoniduak

+0

经过一番调查,我认为这一行的问题 - ko.mapping.fromJS(data。$ values,{},viewModel);因为当我尝试通过alert(data。$ values)显示数据时,它显示的是Object而不是数据。是的,为了避免再次调用viewmodel,我使用clickeevnt作为@GoTo的建议。 –

回答

0

那么。基于@GoTo回答的最终解决方案是: 以下是通过单击数据绑定在viewmodel中调用函数的方法。

<button type="button" class="btn btn-default" id="7" value="7" data-bind="click: getDays.bind($data, '7')">7</button> 

下面是函数。正如你所看到的,我打电话给self.salesdata而不是viewModel。此解决方案工作正常,但不知何故,现在我遇到了这种绑定数据格式的问题 - <td data-bind="text: moment($data.whensold).format('DD.MM', 'ru')"></td>

self.getDays = function (days) { 
        var uri = "/api/sales?days=" + days; 
        $.getJSON(uri, function (data) { 
         ko.mapping.fromJS(data.$values, {}, self.salesdata); 
        }); 
       } 
+0

我应该给予奖励哪个答案? @ brader24与Goto一样都给出了解决方案的想法。 –

+0

我确实提出了所有答案,所以我希望没有人受伤。 –

6

我是新来的这一切,但如果我正确地读你的代码,你正在呼吁视图模型的新实例,而不是说被绑定到HTML文档的一个请求的功能。您需要在初始获取呼叫完成后创建的视图模型上进行请求调用。

更新: 对不起,我本来应该更具体的了解,我指的是代码。在你的代码块结束时,您有以下代码:

$(".btn-default").click(function() { 
     days = $(this).val(); 
     var uri = "/api/sales?days=" + days;  
     new viewModel().request(uri); 
    }); 

在这段代码中,似乎每个默认按钮被点击时,都会创建一个新的视图模型和请求函数被调用该视图模型。

在你定义了什么情况的销售数据被加载后,你有下面的代码是什么创造了HTML文件实际上是绑定到视图模型文档准备功能:

var vm = new viewModel(); 
    vm.salesdata(data.$values); 
    ko.applyBindings(vm); 

在这个视图模型上什么都没有调用请求函数。我想知道你真正想要的是以什么方式将此视图模型中的请求函数绑定到默认按钮。

+1

对于那些投票反对包括评论他们拒绝投票的人来说,这将会有所帮助。我怀疑只是因为我冲我的答案,并没有确保它用例子代码清楚。你有权接受你的意见,但我只想知道为什么,以便我可以尝试改善我未来的答案。 – brader24

+0

你是对的。我的错。这个问题有两个答案,GoTo是非常详细的,并提到了点击处理程序的一个重要点,而我发现你有点通用。问题提出者在这里似乎需要更多细节。因此我提出了GoTo的回答,并低估了你的回答。您现在已经编辑并改进了您的答案,因此我已删除了downvote。我不好评论。 –

+0

我会downvote,因为这个答案没有如何更新原始viewmodel,因为我会说OP正在尝试做。 – vapcguy

5

我会尝试更新视图模型salesdata观察到,通过给予context: self并使用以下方法success

self.request = function (uri) { 
     $.ajax({ 
      url: uri, 
      contentType: 'application/json', 
      context: self, 
      data: [], 
      type: 'GET', 
      cache: false, 
     success: function (data) { 
      this.salesdata(data.$values); 
     } 
     }); 
    } 

编辑:

我可以看到你连接一个click事件使用jQuery。 您应该使用淘汰赛CLCK而不是绑定:

<button data-bind="click: clickEvent" value="1">Click me!</button> 

并在视图模型

clickEvent: function (data, event) { 
    days = event.target.value; 
    var uri = "/api/sales?days=" + days;  
    data.request(uri); 
} 

这样,当你与new viewModel().request(uri);

对于确实可以检索您的视图模型,而不是创建一个新的更多关于点击绑定的信息,请参阅http://knockoutjs.com/documentation/click-binding.html

+0

不是。这不是很好。 –

+0

有没有错误? –

+0

不,没有。 –

3

根据@ brader24在这里:

在您的更新按钮的click事件,可以使用此行代码:

new viewModel().request(uri);

那是什么做的是创造一个viewModel(从您已经实例化一个单独的并已申请绑定),并通过您的request函数填充可观察数组。它根本不会影响你原来的viewModel(它在DOM上应用绑定的那个)。所以你不会看到任何错误,但是你也不会看到页面上发生的任何事情,因为你所做的只是在内存中创建一个新的viewModel,用数据填充它,并且什么也不做。

试试这个代码(在你的viewModel函数看起来很好)。

$(document).ready(function() { 
    var vm = new viewModel(); // declare (and instantiate) your view model variable outside the context of the $.ajax call so that we have access to it in the click binding 
    $.ajax({ 
     url: "/api/sales", 
     type: "GET", 
     cache: false, 
    }).done(function (data) { 
     vm.salesdata(data.$values); 
     ko.applyBindings(vm); 
    }).error(function (xhr, status, error) { 
     var err = eval("(" + xhr.responseText + ")"); 
     alert(err.Message); 
    }); 
    //Here i'm calling for ViewModel update 
    $(".btn-default").click(function() { 
     days = $(this).val(); 
     var uri = "/api/sales?days=" + days;  
     vm.request(uri); // don't use a new instance of a view model - use the one you have already instantiated 
    }); 
}); 

使用淘汰赛点击绑定,而不是安装使用jQuery通常是推荐的路线Click事件处理程序,但它是没有必要的 - 让你现有的代码(与上面的修改)应该工作正常。欲了解更多信息,请参阅Using unobtrusive event handlers敲除文档

+0

这就是我所说的,但没有足够清楚地描述。我更新了我的答案,但这个答案更好地解释了它,并提供了一个解决方案,这是我目前没有准备提供的经验。 – brader24

+0

伙计们,你的建议看起来很合理,但不幸的是它不起作用。 –