KnockoutJS Observable Matriz de objetos Observables

Me gustaría mostrar un editable lista de elementos, cada elemento de los que se puede editar (como una especie de grid editable, de una manera). Estoy usando KnockoutJS. No puedo utilizar un simple Observables de la Matriz, ya que los estados de documentación «Un observableArray pistas en las que los objetos están en la matriz, no el estado de los objetos»

Así, he creado una observableArray de objetos observables (utilizando utils.arrayMap), y salta a la vista. Sin embargo, el problema es que si puedo editar los datos en la pantalla de entrada de datos los cambios que hace el usuario en la pantalla no parecen tener efecto. Ver http://jsfiddle.net/AndyThomas/E7xPM/

¿Qué estoy haciendo mal?

<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/2.0.0/knockout-min.js" type="text/javascript"></script>

<table>
   <tbody data-bind="template: { name:'productListJavascriptTemplate', foreach: products}">
   </tbody>
</table>


<script type="text/html" id="productListJavascriptTemplate">
<tr>
    <td>Name: <input data-bind="value: Name"/></td>
    <td>Name: <span data-bind="text: Name"/></td>
    <td><select data-bind="options: this.viewModel.categories, 
        optionsText: 'Name', optionsValue: 'Id', value: CategoryId,
        optionsCaption: 'Please select...'"></select></td>
    <td>CategoryId: <input data-bind="value: CategoryId"/></td>

</tr>

</script>​

var categoryList= [
{
   Name: "Electronics",
   Id: "1"},
{
   Name: "Groceries",
   Id: "2"}
];

var initialData= [
{
   Name: "Television",
   CategoryId: "1"},
{
   Name: "Melon",
   CategoryId: "2"}
];

var viewModel = {
    products: ko.observableArray(
        ko.utils.arrayMap(initialData, function(product) { 
                                return ko.observable(product); 
        })),
    categories: ko.observableArray(categoryList)       
};


$(function() {
    ko.applyBindings(viewModel);

});

InformationsquelleAutor Andy Thomas | 2012-04-06

3 Kommentare

  1. 19

    ko.utils.arrayMap no mapa de su viewmodel propiedades del observables, y por eso no los ves se actualiza dinámicamente.

    Si define su CategoryId como un observable, verás que se actualiza de la forma esperada:

    var initialData = [
        {
            Name: "Television",
            CategoryId: ko.observable("1")
        },
        {
            Name: "Melon",
            CategoryId: ko.observable("2")
        }
    ];

    Ver esta actualizado jsfiddle: http://jsfiddle.net/tuando/E7xPM/5/

    • perfecto thanksssss!
  2. 16

    Para el seguimiento de Tuan respuesta, necesitaba llenar mis objetos basado en datos obtenidos a partir de un método de servidor de un ASP.Net controlador MVC, donde la lista de Productos está contenida en la vista del Modelo, y la lista de categorías para el cuadro de lista desplegable en el ViewBag. He utilizado el siguiente código (ver también http://www.knockmeout.net/2011/04/utility-functions-in-knockoutjs.html):

    var initialData = @Html.Raw( new JavaScriptSerializer().Serialize(Model));
    var categoryList = @Html.Raw( new JavaScriptSerializer().Serialize(ViewBag.CategoryList));
    
    var ObservableProduct = function(name, description, categoryId) {         
        this.Name = ko.observable(name);         
        this.Description = ko.observable(description);
        this.CategoryId = ko.observable(categoryId);
    };  
    
    var viewModel = {
        products: ko.observableArray(ko.utils.arrayMap(initialData, function(product) { 
                return new ObservableProduct(product.Name, product.Description, product.CategoryId); 
            })),
        categories: ko.observableArray(categoryList)       
    };
    
    $(function() {
        ko.applyBindings(viewModel);
    
    });

    Gracias, Tuan!

  3. 1

    Estoy usando escritura calculada observables que se inicializan en la llamada a ko.utils.arrayMap

    Puede ser una exageración en su caso, pero podría ayudar a alguien más. Ver este
    jsFiddle de la muestra

      //Writeable computed observables
      function Customer(id, firstName, lastName, preferred) {
         var self = this;
         self.id = id;
         self.firstName = firstName;
         self.lastName = lastName;
         //Non-Writeable computed observable
         self.fullName = ko.computed(function() {
            var fn = self.firstName;
            var ln = self.lastName;
            return ln ?  fn + ' ' + ln : fn;
         }, self);
         self.preferred = ko.observable(preferred);
         //Writeable computed observable
         self.isPreferred = ko.computed({
            read: function() {
               var preferredStr = self.preferred() || '';
               var isPreferredComputed = preferredStr.toUpperCase();
               return (isPreferredComputed === 'Y') ?  true : false;
            },
            write: function(value) {
               self.preferred( (!value) ? '' : (value ? 'Y' : ''));            
            },
            owner: self        
        });    
     }
      var mappedData = ko.utils.arrayMap(dataFromServer, function(customer) {
          return new Customer(customer.id, customer.firstName, customer.lastName, customer.preferred);
      });

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea