如何在knockout中绑定viewmodel的集合

How to bind a collection of viewmodel in knockout

首先,我对淘汰赛很陌生,但我知道它使用的 MVVM 模式,因为我已经在 WPF 中完成了很多时间...顺便说一句,我有以下需要。

我需要用艺术家类型列表和将要出现的艺术家数量填充 bootstrap 网格。设置它应该计算每行总数的数字。

这是我的 .cshtml(但它也适用于其他语言)

<div class="container" id="composizioneArtistiContainer">
    <div data-bind="foreach: RenderedArtisti">
        <div class="row">
            <div class="col-md-2">
                <p data-bind="text: descrizione" />
            </div>

            <div class="col-md-2">
                <input id="inpDataRichiesta" type="text" class="form-control" data-bind="value: numero" />
            </div>

            <div class="col-md-2">
                <p data-bind="text: prezzo" />
            </div>

            <div class="col-md-2">
                <p data-bind="text: totalePrezzo" />
            </div>
        </div>
    </div>

    <div class="row">
        <div class="col-md-2">
             Spese fisse
        </div>
        
        <div class="col-md-4">
            
        </div>

        <div class="col-md-2">
            <p data-bind="text: SpesaFissa" />
        </div>
    </div>
    
    <div class="row">
        <div class="col-md-2">
            Totale spese 
        </div>
        
        <div class="col-md-4">
            
        </div>

        <div class="col-md-2">
            <p data-bind="text: TotaleSpese" />
        </div>
    </div>
</div>

现在在我的视图模型中:

function ComposizionePrenotazioneArtistiViewModel() {
    var self = this;
    self.SpesaFissa = 70;
    self.RenderedArtisti = ko.observableArray([]);
    self.TotaleSpese = ko.computed(function() {
        return self.SpesaFissa;
    });

    GetRenderedAssociazioneArtistiPrenotazione(self.RenderedArtisti);
}

这是 js 文件

$(document).ready(function () {
    ko.applyBindings(new ComposizionePrenotazioneArtistiViewModel(), document.getElementById("composizioneArtistiContainer"));
});

function GetRenderedAssociazioneArtistiPrenotazione(artisti) {

    AjaxRequest(
        BaseUrlJumpApiClownOnDemand + 'api/artistaTipo/',
        'GET',
        null,
        function (response) {
            var arrayLength = response.length;
            for (var i = 0; i < arrayLength; i++) {
                artisti.push({
                    descrizione: response[i].descrizione,
                    codice: response[i].codice,
                    prezzo: response[i].prezzo,
                    numero: 1,
                    totalePrezzo: ko.pureComputed(function () {
                        return self.numero;
                    })
                });
            }
        },
        function (jqXHR, textStatus, errorThrown) {
            ShowErrorService(jqXHR, textStatus, errorThrown);
        });

...OMISS...

I think I am doing something wrong with the artisti passed since when I update the number of 'numero' it doesn't recalculate the TotalePrezzo.

Any advice?

Thanks

您需要添加一个函数来保存每个 'artistaTipo':

function ArtistaTipo(artistaTipo) {
  let self = this;
  this.descrizione = ko.observable( artistaTipo.descrizione);
  this.codice = ko.observable( artistaTipo.codice);
  this.prezzo = ko.observable( artistaTipo.prezzo);
  this.numero = ko.observable(1);
  
  self.totalePrezzo = ko.pureComputed(function() {
    return self.numero();
  })    
}

所有字段都是可观察的,因为您有一个计算可观察对象。

然后修改你的GetRenderedAssociazioneArtistiPrenotazione中的push:

function GetRenderedAssociazioneArtistiPrenotazione(artisti) {

    AjaxRequest(
        BaseUrlJumpApiClownOnDemand + 'api/artistaTipo/',
        'GET',
        null,
        function (response) {
            var arrayLength = response.length;
            for (var i = 0; i < arrayLength; i++) {
                artisti.push( 
                   new ArtistaTipo(response[i])
                );
            }
        },
        function (jqXHR, textStatus, errorThrown) {
            ShowErrorService(jqXHR, textStatus, errorThrown);
        }
    );
}

这是一个fiddle。我更改了硬编码数组的 Ajax 调用。