6

基本的に、KnockoutとJSONオブジェクトを介してBootstrapテンプレートにデータを入力しようとしています。

ブートストラップ足場:

<div class="row-fluid">
    <div class="span4">
        <h1>App Title</h1>
        <p>App Description</p>
    </div>
    <div class="span4">
        <h1>App Title</h1>
        <p>App Description</p>
    </div>
    <div class="span4">
        <h1>App Title</h1>
        <p>App Description</p>
    </div>
</div>
<div class="row-fluid">
    <div class="span4">
        <h1>App Title</h1>
        <p>App Description</p>
    </div>
    <div class="span4">
        <h1>App Title</h1>
        <p>App Description</p>
    </div>
    <div class="span4">
        <h1>App Title</h1>
        <p>App Description</p>
    </div>
</div>
...

使用しているノックアウトコードは次のとおりです。

var viewModel;

$.get('AppData.json', function (data) {
    jsonData = $.parseJSON(data);
    viewModel = ko.mapping.fromJS(jsonData);
    var apps = viewModel.Apps();
    ko.applyBindings(viewModel);
});

問題は、インデックスモジュロ3の条件付きノックアウトを実行した後、ノックアウトに必要なものを注入させることができないこと</div><div class="row-fluid">です...これらの<div>タグがぶら下がっている/閉じられていないためだと思います。

要するに、viewModel.Apps();オブジェクトの配列を上記のBootstrapスキャフォールディング内に収めるにはどうすればよいですか?

4

3 に答える 3

10

appsobservable / observable配列を3つの要素の配列にスライスする計算されたobservableを作成し、バインドを使用してルート要素をforeachバインドします。このようなもの。

観察可能:

viewModel.appRows = ko.computed(function() {
    var apps = this.Apps();
    var result = [];
    for (var i = 0; i < apps.length; i += 3) {
        var row = [];
        for (var j = 0; j < 3; ++j) {
            if (apps[i + j]) {
                row.push(apps[i + j]);
            }
        }
        result.push(row);
    }
    return result;
}, viewModel);

マークアップ:

<div class="container" data-bind="foreach: appRows">
    <div class="row-fluid" data-bind="foreach: $data">
        <div class="span4">
            <h1 data-bind="text: title"></h1>
            <p data-bind="text: description"></p>
        </div>
    </div>
</div>
于 2012-08-25T19:22:30.010 に答える
7

非常によく似た問題を自分で解決する必要がありました。監視可能な配列を使用してブートストラップグリッドをレンダリングしますが、ブートストラップv3とkov3.0を使用します。今後の参考のために、ソリューションをここに残しておきます。

バインディングはデフォルトでそれらを使用して実装されているため、計算された関数の代わりにプレーン関数を使用しています(RP Niemeyerの回答はこちらhttps://stackoverflow.com/a/6712389/323751を参照)

私のビューモデルでは:

this.partitioned = function (observableArray, count) {
    var rows, partIdx, i, j, arr;

    arr = observableArray();

    rows = [];
    for (i = 0, partIdx = 0; i < arr.length; i += count, partIdx += 1) {
        rows[partIdx] = [];
        for (j = 0; j < count; j += 1) {
            if (i + j >= arr.length) {
                break;
            }
            rows[partIdx].push(arr[i + j]);
        }
    }
    return rows;
};

レンプレート:

<div data-bind="foreach: partitioned(userProjects, 3)">
  <div class="row"
       data-bind="template: { name: 'projectCell', foreach: $data }"></div>
</div>

<script id="projectCell" type="text/html">
  <div class="col-md-4" data-bind="text: name"></div>
</script>

誰かがこれが役に立つと思うことを願っています。

于 2013-12-11T19:21:06.547 に答える
1

私はbootstrap3を使用しており、行ごとにx個のオブジェクトが必要です。xはウィンドウサイズ(colクラスなど)によって異なります。

たとえば、クラスを持つ要素があります:

col-lg-2 col-md-2 col-sm-3 col-xs-4

それで

xsの場合、行には3つのアイテムがあります

lgの場合、行には6つのアイテムがあります...

私はそれを機能させるためにrkhayrovの答えを拡張しました

/* determine the current bootstrap environment */
function findBootstrapEnvironment() {
    var envs = ['xs', 'sm', 'md', 'lg'];

    $el = $('<div>');
    $el.appendTo($('body'));

    for (var i = envs.length - 1; i >= 0; i--) {
        var env = envs[i];

        $el.addClass('hidden-'+env);
        if ($el.is(':hidden')) {
            $el.remove();
            return env
        }
    };
}


/* determine How many objs per row */
function determineObjectsPerRow(){
    switch(findBootstrapEnvironment()) {
        case 'xs':
            return 3;
            break;
        case 'sm':
            return 4;
            break;
        case 'md':
            return 6;
            break;
        case 'lg':
            return 6;
            break;
    }
}


        var objsPerRow= determineObjectsPerRow();

        for (var i = 0; i < apps.length; i += objsPerRow) {
            var row = [];
            for (var j = 0; j < objsPerRow; ++j) {
                if (apps[i + j]) {
                    row.push(apps[i + j]);
                }
            }
            result.push(row);
        }

監視可能な幅と高さに依存関係を追加したので、ウィンドウのサイズが変更されると関数が再計算されます

var base = {
    AppModel:function (data) {
        var self = this;
        self.data = ko.observable({
            documents:ko.observableArray([]),
            width:ko.observable($(window).width()),
            height:ko.observable($(window).height())
        });

        /* calculate rows based on bootstrap environment */
        self.appRows = ko.computed(function() {
            self.data().height();
            self.data().width();
            var apps = self.data().documents();
            var result = [];
            var objsPerRow= determineObjectsPerRow();

            for (var i = 0; i < apps.length; i += objsPerRow) {
                var row = [];
                for (var j = 0; j < objsPerRow; ++j) {
                    if (apps[i + j]) {
                        row.push(apps[i + j]);
                    }
                }
                result.push(row);
            }
            return result;
        }, self); 

    },
};

およびサイズ変更ハンドラー

$(window).resize(function(event) {
    vm.data().height($(window).height());
    vm.data().width($(window).width());
});

シャルムのように機能し、デバイス幅ごとに行が適切に生成されます

誰かが同じことを達成する必要がある場合は、ここに残します

于 2015-06-17T11:27:59.147 に答える