LaloLoop
LaloLoop

Reputation: 2143

ko.mapping shows function in input fields insted of value

I'm having an issue with ko.mapping plugin for knockout. I've been thoroughly searching for an answer but couldn't find anything.

I'm using knockout in conjunction with boilerplate js, but I think that's not the problem.

Here's the JS:

define(function(require){
var Boiler = require('Boiler'),
    komapping = require('knockout_mapping');

ko.mapping = komapping;

var mapping = {
                'observe': ['disciplina',
                            'numero',
                            'paraUsoEn',
                            'detalleCertificadoCalidad',
                            'comentariosGenerales']
              };

var RequisicionViewModel = function(moduleContext, params, bindingCallback){
    /* Propiedades del modelo */
    var self = this;
    this.disciplinas = ko.observableArray();
    this.requisicion = ko.mapping.fromJS({});

    /* Obtener los valores del WS */

    // Obtener las disciplinas
    moduleContext.requestor.get('/disciplina/').done(function(data){
        self.disciplinas(data);
    });

    // Obtener la plantilla de la requisición
    moduleContext.requestor.get('/requisicion/ZFN-5612').done(function(data){

        ko.mapping.fromJS(data, mapping, self.requisicion);

        self.requisicion.planos = ko.observable("Jola!")

        // Aplicar el binding
        bindingCallback();
    });

    /* Gestión de eventos */
    this.onGuardarClicked = function(){

        console.log(ko.mapping.toJSON(self.requisicion));

    };
};

return RequisicionViewModel;
});

As you can see I define only the objects I want to be observable.

Here's the HTML

<div id="uso-planos-informacion" class="clearfix" data-bind="with:requisicion">
    <div class="control-grp">
        <label for="usarse-en" class="text-solid">{{nls.label_usarse_en}}</label>
        <input id="usarse-en" 
               type="text"
               data-bind="value:paraUsoEn">
    </div>

    <div class="control-grp">
        <label for="planos" class="text-solid">{{nls.label_planos}}</label>
        <input id="planos" 
               type="text">
    </div>

    <div class="control-grp">
        <label for="certificado-calidad" class="text-solid">{{nls.certificado_calidad}}</label>
        <input id="certificado-calidad" 
               type="text"
               data-bind="value:detalleCertificadoCalidad">
    </div>
</div><!--  Termina uso-planos-informacion -->

It's much longer, but for brevity I'll just paste 2 fields that show the error. Finally when I run it, this is what happens:

https://i.sstatic.net/2Vasm.png

Here's what I've tried so far:

This works, but the observable looses it's properties or something like that because it does not get updated again after this.

And does not work. The value does not appear, neither it can be updated.

Hope Someone has solved this kind of problem, otherwise I'll have to do the mapping manually (which works!).

Thanks!

Upvotes: 0

Views: 128

Answers (1)

LaloLoop
LaloLoop

Reputation: 2143

Well, after following the suggestion from @Salvador Dali, I was creating a more reproducible example, and by doing this I could find the solution. Since I'm using require.js to load my libraries I found out that there was a problem with knockout. Although knockout was included as a script in my index.jsp, it was not working properly.

The solution consists in configuring knockout inside main.js (boilertplatejs file) like the following:

paths:{
        …
        knockout : 'path_to_knockout js',
        knockout_mapping : 'path_to_knockout_mapping js',
        …
},
shim : {
       …
       'knockout_mapping' : {
           deps : ['knockout'],
           exports: 'ko.mapping'
       }
       …
}

You can leave knockout reference inside index.jsp if you want, and if you already have components or modules built it will prevent them from breaking.

Inside your component you'll need this:

var ko = require('knockout');

And inside your viewmodel.js, add this:

var komapping = require('knockout_mapping'),
    ko = require('knockout');

ko.mapping = komapping;

This way I've been able to map json data (mapped as normal JS object by jquery), into observables.

Additional information.

  • Knockout version: 3.2.0 (version 3.1.0 produces an error about ko not being defined).
  • KO Mapping version: 2.4.1
  • jquery version: 1.7.1
  • underscore-1.3.3_1

Thanks!

Upvotes: 0

Related Questions