문제

I have my view model:

function (dataservice, Person){
    var genders = ko.observableArray();
    var languages = ko.observableArray();
    var person = ko.observableArray();

    function activate(){
        dataservice.getGenders(genders);
        dataservice.getGenders(languages);
    }

    var vm = {
        genders: genders,
        languages: languages,
        person: person
    };
}

function Person(person){
    var firtstName = person.firtstName;
    var familyName = person.familyName;
    var genderId = person.genderId;
    var languageId = person.languageId;
}

It's simplified for clarity.

Then I have my `Genders' data from server, it looks like this:

[{
    $id: "1",
    GenderId: 2,
    GenderName: "Female",
    GenderDescription: "Female",
    GenderCode: "F"
}]

I also have Languages that looks like this:

[{
    "$id": "1",
    "LanguageId": 2,
    "LanguageName": "Afar",
    "LanguageDescription": "Afar",
    "LanguageCode": "aa"
}]

What I am trying to achieve is to bind the genders array from my view model as a data source and use Person.GenderId as the value to be updated, in a way such that the correct radio button is initially selected. This selection depended on Person.GenderId.

I did something similar with Languages using a drop down and that works just fine:

<section data-bind="with: $root.personModel">
   <select id="language" 
           data-bind="options: $root.languages, 
                      optionsText: 'LanguageName', 
                      optionsValue: 'LanguageId',
                      value: LanguageId, 
                      optionsCaption: 'none'">
    </select>
</section>

Now I am trying to do the same thing with radio buttons, but I don't know how to make it work. Here's what I have:

<section data-bind="with: $root.personModel">
   <!-- ko foreach: $root.genders -->
   <input type="radio" 
          name="genders" 
          data-bind="attr: {value: GenderId}, checked: GenderId" />
   <span data-bind="text: $data.GenderName"></span>
   <!-- /ko -->
</section>

If I understood things correctly, the foreach binding works like with and changes my context, so I can't reach GenderId from my exposed Person.

도움이 되었습니까?

해결책

change

<input type="radio" name="genders" data-bind="attr: {value: GenderId}, checked: GenderId" />

to

<input type="radio" name="genders" data-bind="attr: {value: GenderId}, checked: $parent.GenderId" />

as explained here

$parent: This is the view model object in the parent context, the one immeditely outside the current context. In the root context, this is undefined.

다른 팁

You will need to utilize the checkdValue binding, see the lower part of the "checked" documentation.

Your code didn't quite translate to a repro, but here's my version more or less in your scenario. Suppose this bit of code:

var Person = function(person) {
    var self = this;
    self.name = ko.observable(person.name);
    self.gender = ko.observable(person.gender);
};

var root = {
    genders: [{ $id: "1", GenderId: 1, GenderName: "Female"},
              { $id: "2", GenderId: 2, GenderName: "Male"}]
};

root.personModel = new Person({name: 'john', gender: root.genders[1]});

ko.applyBindings(root);

Alongside this markup:

<section data-bind="with: $root.personModel">
    <!-- ko foreach: $root.genders -->
    <input type="radio" 
           name="genders" 
           data-bind="checkedValue: $data, checked: $root.personModel.gender" />
    <span data-bind="text: $data.GenderName"></span><br />
    <!-- /ko -->
</section>

This should work, see this fiddle.

The objects from the genders array are bound to the checkedValue of each input, and the personModel's gender is bound to checked.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top