2013-06-05 21 views
2

有一個模型叫顧客:我我如何調用一個函數在一個ViewModel淘汰賽

function customer(id, name, age, comments) { 
    var self = this; 

    self.Id = id; 
    self.Name = name; 
    self.Age = age, 
     self.Comments = comments; 

    self.addCustomer = function() { 
     $.ajax({ 
      url: "/api/customer/", 
      type: 'post', 
      data: ko.toJSON(this), 
      contentType: 'application/json', 
      success: function (result) { 
       //SOMETHINGS WRONG HERE 
       customerVM(); 
      } 
     }); 
    } 
} 

後,我添加客戶的客戶名單犯規自動更新。在模型中調用customerVM()會進入viewModel函數,但永遠不會進入getCustomers函數,所以我必須調用viewModel錯誤。那就是我從調試中看到的。

顯示的列表功能是在視圖模型:

function customerVM() { 
    var self = this; 
    self.customers = ko.observableArray([]); 
    self.getCustomers = function() { 
     self.customers.removeAll(); 
     $.getJSON("/api/customer/", function (data) { 
      $.each(data, function (key, val) { 
       self.customers.push(new customer(val.Id, val.Name, val.Age, val.Comments)); 
      }); 
     }); 
    }; 
} 

我需要添加一個客戶後,不知何故調用GetCustomers的。我該怎麼做?

這裏是客戶html的

<table > 
    <thead> 
     <tr> 
      <th>Id</th> 
      <th>Name</th> 
      <th>Age</th> 
      <th>Comments</th> 
     </tr> 
    </thead> 
    <tbody data-bind="foreach: customers" > 
     <tr> 
      <td data-bind="text: Id"></td> 
      <td data-bind="text: Name"></td> 
      <td data-bind="text: Age"></td> 
      <td data-bind="text: Comments"></td> 
     </tr> 
    </tbody> 
</table> 
<br /> 
<input type="button" id="btnGetCustomers" value="Get Customers" data-bind="click: getCustomers" /> 

回答

1

我想你在這裏問的更深層的問題是關於如何在瀏覽器中管理你的數據,並保持它與服務器上的數據同步。我昨天回答了一個類似的問題,你可以在這裏閱讀:Adding new elements to a knockout observable array - best practices?

在你的問題和代碼中,它看起來像你試圖插入一個新的客戶到服務器,然後讀取整個客戶列表回到你的插入後查看模型。你可能需要你沒有提到的這個,但通常這種模式是沒有必要的。

用於需要最常見的情況下,從服務器讀取一個後插入到該服務器的檢索剛添加的對象的服務器生成的標識符。對於大多數MV *瀏覽器端框架(包括Knockout),「插入」api調用通常會返回新元素的ID(或者需要返回的數據量),並且只需更新客戶端版本帶有新ID的模型。如果ID屬性是可觀察的,則淘汰賽會自動更新您的用戶界面。這裏有一個例子:

var customer = function(name, age, comments){ 
    var self = this; 
    self.id = ko.observable();//unknown when created in the browser 
    self.name = ko.observable(name); 
    self.age = ko.observable(age); 
    self.comments = ko.observable(comments); 
} 

var customersViewModel = function(){ 
    var self = this; 
    self.customers = ko.observableArray([]); 
    self.addCustomer = function(customer){ 
     self.customers.push(customer); 
     $.ajax({ 
      url: "/api/customer/add", 
      type: 'post', 
      data: ko.toJSON(this), 
      contentType: 'application/json', 
      success: function (result) { 
       //assuming result will contain the server-side customer id 
       //we provide that value to our customer's id observable 
       //and knockout will update the UI 
       customer.id(result.newCustomerId); 
       //no need to update the entire array, and 
       //our 'customer' has already been pushed into our 
       //observable array so we're done. 
      } 
     }); 
    } 
} 

當客戶處於「待定」狀態(當瀏覽器在等待服務器向刀片API調用響應),你知道,客戶不會有一個ID。你可以在你的綁定中使用它來向你的客戶申請一個「待定」類,如下所示:

<tbody data-bind="foreach: customers" > 
    <tr data-bind="css : {'pending': !id()}"> 
     <td data-bind="text: id"></td> 
     <td data-bind="text: name"></td> 
     <td data-bind="text: age"></td> 
     <td data-bind="text: comments"></td> 
    </tr> 
</tbody> 

我希望這有助於!

2

我覺得你的設計實際上有一些缺陷。首先,你不想在你所謂的ko.applyBindings(vm);後(我實際上沒有看到任何地方在你的HTML)

某處在你的HTML頁面,你應該有任何一點被調用customerVM()

<script type="text/javascript"> 
    var vm = new customerVM(); 
    ko.applyBindings(vm); 
</script> 

其次,認爲customerVM()含有的customers集合,負責管理您的收藏customers的填充,以及通過集合(或單個customer)到您的API進行持久化。這意味着,我會將addCustomer函數從客戶對象中移出並將其移入customerVM。

// customer is just a simple data object 
    function customer(id, name, age, comments) { 

      var self = this; 
      self.Id = ko.observable(id); 
      self.Name = ko.observable(name); 
      self.Age = ko.observable(age); 
      self.Comments = ko.observable(comments); 
    } 

    function customerVM() { 

     var self = this; 
     self.customers = ko.observableArray([]); 

     self.getCustomers = function() { 
      self.customers.removeAll(); 
      $.getJSON("/api/customer/", function (data) { 
       $.each(data, function (key, val) { 
        self.customers.push(new customer(val.Id, val.Name, val.Age, val.Comments)); 
       }); 
      }); 
     }; 

     self.addCustomer = function (customer) { 
      // pass in a single customer for persistence 
     } 
} 
+0

在模型中調用customerVM()會進入viewModel函數,但永遠不會進入getCustomers函數,所以我必須調用viewModel錯誤。那就是我從調試中看到的 –

1

如果已經執行像湯姆applyBindings曾建議:

<script type="text/javascript"> 
    var vm = new customerVM(); 
    vm.getCustomers(); 
    ko.applyBindings(vm); 
</script> 

然後你addCustomer方法應該是這個樣子:

self.addCustomer = function() { 
    $.ajax({ 
     url: "/api/customer/", 
     type: 'post', 
     data: ko.toJSON(this), 
     contentType: 'application/json', 
     success: function (result) { 
      vm.getCustomers(); //*******THIS IS THE CHANGE YOU NEED 
     } 
    }); 
} 

雖然,我同意湯姆它將addCustomer方法移入根模型會更合適。