2014-04-25 70 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

夥計們,你的建議看起來很合理,但不幸的是它不起作用。 –