2012-04-01 27 views
12

Tôi đang cố thiết lập lưới và cập nhật lưới bằng nhiều bản ghi hơn thông qua JSON. Trong ví dụ đơn giản này, tôi có thể đạt được các chức năng cần thiết nhưng tôi chỉ có thể cập nhật/đẩy một bản ghi JSON. Tôi muốn có thể thêm nhiều bản ghi thông qua JSON? Làm thế nào tôi có thể đạt được điều này? Tôi giả sử tôi có thể phải tạo ra một số loại vòng lặp và đẩy mỗi kết quả JSON đến quan sát được nhưng tôi hy vọng rằng loại trực tiếp có thể có cách tốt hơn để cập nhật/phân tích cú pháp thông qua JSON?Cập nhật Knockout.js Có thể quan sát được từ JSON

Heres một bản sao của những gì tôi đã đạt được cho đến nay: http://jsfiddle.net/sparkhill/crSbt/

 function Users(user_id, password) { 
    this.user_id = ko.observable(); 
    this.password = ko.observable(); 
} 

var viewModel = { 

    users: ko.observableArray([]), 


    addUser: function() { 
     this.users.push({ 

      user_id: "", 
      password: "" 
     }); 
    }, 

    addJSON: function() { 


     //Works Fine 
     var JSONdataFromServer 
     ='{"user_id":"frances","password":"password"}'; 

     //More than one result - wont map - Would Ideally like to map lots of records at one time 
//var JSONdataFromServer ='{"user_id":"frances","password":"password"}, {"user_id":"frances","password":"password"}'; 

     var dataFromServer = ko.utils.parseJson(JSONdataFromServer); 


     this.users.push(dataFromServer); 

     //Tried 
     //this.users.push(JSON.parse(JSONdataFromServer)); 


    } 

}; 

viewModel.users(); 
ko.applyBindings(viewModel); 

    </script> 

Cập nhật này dường như làm việc nhưng tôi tự hỏi, nếu họ là một phương pháp hiệu quả hơn?

addJSON: function() { 

     //Works Fine 
     var JSONdataFromServer 
     ='[{"user_id":"frances","password":"password"},{"user_id":"timmy","password":"password"}]'; 

     var results = JSON.parse(JSONdataFromServer); 

     var i = results.length; 

     for(var i = 0; i < results.length; i++){ 

      this.users.push(results[i]); 
     }; 

Trả lời

22

Dưới đây là 3 cách để bạn có thể làm điều này ... tìm thấy trong fiddle này: http://jsfiddle.net/johnpapa/nfnbD/

1) Sử dụng ko .utils.arrayPushAll chức năng 2) sử dụng logic của riêng bạn 3) Viết chức năng của riêng bạn trên observableArray

Chi tiết ...

1) Nếu bạn sử dụng hàm ko.utils.arrayPushAll, bạn sẽ cần gọi giá trịĐã bị vô hiệu vì mảng này bị tự ghi đè một cách hiệu quả. Các quan sát không cháy unles bạn nói với nó rằng nó đã thay đổi. Đây là cách bạn có thể làm điều đó:

ko.utils.arrayPushAll(this.users(), dataFromServer); 
this.users.valueHasMutated(); 

2) Lựa chọn thứ hai là để viết logic vòng lặp của riêng bạn, về cơ bản sử dụng mã tương tự như chức năng arrayPushAll như thế này.

for (var i = 0, j = dataFromServer.length; i < j; i++) 
this.users.push(dataFromServer[i]); 

3) Tạo một chức năng của riêng bạn trên observableArray, như thế này:

ko.observableArray.fn.pushAll = function(valuesToPush) { 
     var items = this; 
     for (var i = 0, j = valuesToPush.length; i < j; i++){ 
      items.push(valuesToPush[i]); 
     } 
     return items; 
}; 

Mặc dù mã này trên sẽ thông báo mỗi khi một mục được thêm vào. Vì vậy, nó có thể là tốt hơn để thêm tất cả, sau đó thông báo. Điều này sẽ hiệu quả hơn. Như thế này:

ko.observableArray.fn.pushAll = function(valuesToPush) { 
    var underlyingArray = this(); 
    this.valueWillMutate(); 
    ko.utils.arrayPushAll(underlyingArray, valuesToPush); 
    this.valueHasMutated(); 
    return this; 
}; 

Sau đó gọi nó là như thế này:

this.users.pushAll(dataFromServer); 
+0

lưu ý rằng bạn có thể cần phải tạo biến mẫu của mô hình nếu bạn muốn cập nhật observableArray từ một nơi nào đó trong trang của mình, bên ngoài chính mô hình thực tế, ví dụ: 'var myModelInstance = new ViewModel(); ' ' ko.utils.arrayPushAll (myModelInstance.users(), dataFromServer);' 'myModelInstance.users.pushall –

+1

đây có phải là vẫn còn con đường để đi với phiên bản 3.1? – Homer

+0

Tôi hỏi cùng câu hỏi với tên Homer. Là 'pushAll' đã có trong cốt lõi của KnockoutJs kể từ phiên bản 3.1. – Samuel

3

Bạn có thể sử dụng mapping Plugin

Xem http://knockoutjs.com/documentation/plugins-mapping.html

+0

như thế nào giúp lập bản đồ plugin với vấn đề này? –

+0

Xem phần "Sử dụng nâng cao" (có sẵn trong bài viết được liên kết). Với plugin, bạn có thể tùy chỉnh quá trình cập nhật/tạo –

1

Tôi biết điều này là một bài khá cũ nhưng tôi đi qua nó và chỉ cần nghĩ rằng tôi muốn hiển thị một cách khác để làm điều này trong loại trực tiếp mà không cần tạo pushAll của riêng bạn cho bất kỳ khách truy cập nào trong tương lai.

Bạn có thể sử dụng push.apply khi loại trực tiếp trên một mảng có thể quan sát được. Điều này sẽ cho phép bạn đẩy nhiều phần tử từ máy chủ và chỉ kích hoạt một thông báo.

Example in JsFiddle

Sửa: Các further reading cho bất cứ ai đọc bài viết này ai muốn biết lý do tại sao sử dụng push.apply thay vì sử dụng push trong một vòng lặp

Các vấn đề liên quan