1

私はこのようなモデルを持っています

function ViewModel(){
    var self = this

    self.Choices            =   ko.observableArray([])
    self.AcceptedChoices    =   ko.observableArray([])

    self.LoadData   =   function(){
        self.ViewAnswered()
    }   

    self.ViewAnswered = function(){
        var url =   'QuestionsApi/ViewAnswered'
        var type    =   'GET'
        ajax(url , null , self.OnViewAnsweredComplete, type )                   
    }
    self.OnViewAnsweredComplete = function(data){
        var currentAnswer = data.Answer

        self.Choices(currentAnswer.Choices)
        self.AcceptedChoices(currentAnswer.AcceptedChoices)
    }       

    self.LoadData()         
}

これが私のオブジェクトです。余分なものを取り除きました

{
    "AcceptedChoices": [94, 95],
    "Choices": [{
        "ChoiceId": 93,
        "ChoiceText": "Never"
    }, {
        "ChoiceId": 94,
        "ChoiceText": "Sometimes"
    }, {
        "ChoiceId": 95,
        "ChoiceText": "Always"
    }]
}

そして、ここにバインディングがあります

<u data-bind="foreach:Choices">
    <li>
        <input type="checkbox" name="choice[]" data-bind="value:ChoiceId,checked:$root.AcceptedChoices">
        <span data-bind="text:ChoiceText">Never</span>
    </li>
</u>

問題は、選択肢がオブジェクトの配列であるため、チェックボックスがチェックされていないことです。この問題を解決するにはどうすればよいですか? 選択肢が 1 つしかないラジオでも同じことが機能しますが。

4

2 に答える 2

2

ここで解決策を見つけたことを気にしないでください

チェック済みバインディングはプリミティブを適切に比較しません

また、これには2つの方法があります。フィドルで提供されているソリューションは不気味なので、ノックアウト バージョン 3.0.0 を使用するソリューションを使用します。

私がする必要があるのは、他の代わりにknockout-3.0.0.jsをアタッチしてから、のcheckedValue代わりに使用することだけですvalue

<input type="checkbox" name="choice[]" 
    data-bind="
            checkedValue:ChoiceId,
            checked:$root.AcceptedChoices"
>

これで完了です。それが誰かを助けることを願っています。

編集:

Chromeで動作していないことに気付きました。だから私は代替案を見つけました。この2つの関数を作成しました。

self.ConvertToString = function(accepted){
    var AcceptedChoices =   []
    ko.utils.arrayForEach(accepted, function(item) {
        AcceptedChoices.push(item.toString())
    })  
    return  AcceptedChoices
}
self.ConvertToInteger = function(accepted){
    var AcceptedChoices =   []
    ko.utils.arrayForEach(accepted, function(item) {
        AcceptedChoices.push(parseInt(item))
    })  
    return  AcceptedChoices         
}

そして、それらを使用してください

self.AcceptedChoices(self.ConvertToString(currentAnswer.AcceptedChoices))

値を取得するには

AcceptedChoices: self.ConvertToInteger(self.AcceptedChoices()),
于 2013-11-12T10:49:24.930 に答える
0

選択肢の Id が AcceptedChoices 配列にあるかどうかを確認する必要があります。これを行うには、ko.utils 配列関数を使用します。

checked: function() { return ko.utils.arrayFirst($root.acceptedChoices(), function(item){
    return item == ChoiceId();
} !== null }

これをルート オブジェクトの関数に入れることができます。

self.isChoiceAccepted = function(choiceId){
    return ko.utils.arrayFirst($root.acceptedChoices(), function(item){
        return item == choiceId;
    } !== null
};

次に、データバインドで次のように呼び出します。

checked: function() { return $root.isChoiceAccepted(ChoiceId()); }

これはテストされていません。配列内に一致するアイテムが見つからない場合、arrayFirst メソッドが null を返すことを 100% 確信しているわけではないので、それを確認してください。

于 2013-11-12T10:41:53.250 に答える