Подтвердить что ты не робот

KnockoutJS если оператор внутри цикла foreach

Здесь у меня есть этот код:

<tbody data-bind="foreach: entries">
    <tr>
        <td><i class="icon-file"></i> <a href="#" data-bind="text: name, click: $parent.goToPath"></a></td>
        </tr>
</tbody>

Я хотел бы иметь что-то вроде этого (это псевдокод):

<tbody data-bind="foreach: entries">
    <tr>
        <td><i class="{{ if type == 'file' }} icon-file {{/if}}{{else}} icon-folder {{/else}}"></i> <a href="#" data-bind="text: name, click: {{ if type == 'file' }} $parent.showFile {{/if}}{{else}} $parent.goToPath {{/else}}"></a></td>
    </tr>
</tbody>

Можно ли написать что-то подобное на KnockoutJS?

4b9b3361

Ответ 1

Один из вариантов - сделать что-то вроде:

<tbody data-bind="foreach: entries">
    <tr>
        <td>
            <!-- ko if: type === 'file' -->
                <i class="icon-file"></i>
                <a href="#" data-bind="text: name, click: $parent.showFile"></a>
            <!-- /ko -->
            <!-- ko if: type !== 'file' -->
                <i class="icon-folder"></i>
                <a href="#" data-bind="text: name, click: $parent.goToPath"></a>
            <!-- /ko -->
        </td>
    </tr>
</tbody>

Пример здесь: http://jsfiddle.net/rniemeyer/9DHHh/

В противном случае вы можете упростить свое представление, переместив некоторую логику в вашу модель представления, например:

<tbody data-bind="foreach: entries">
    <tr>
        <td>
            <i data-bind="attr: { 'class': $parent.getClass($data) }"></i>
            <a href="#" data-bind="text: name, click: $parent.getHandler($data)"></a>
        </td>
    </tr>
</tbody>

Затем добавьте методы на вашей модели представления, чтобы вернуть соответствующее значение:

var ViewModel = function() {
    var self = this;
    this.entries = [
        { name: "one", type: 'file' },
        { name: "two", type: 'folder' },
        { name: "three", type: 'file'}
    ];

    this.getHandler = function(entry) {
        console.log(entry);
        return entry.type === 'file' ? self.showFile : self.goToPath;
    };

    this.getClass = function(entry) {
        return entry.type === 'file' ? 'icon-file' : 'icon-filder'; 
    };

    this.showFile = function(file) {
        alert("show file: " + file.name);
    };

    this.goToPath = function(path) {
        alert("go to path: " + path.name);
    };
};

Пример здесь: http://jsfiddle.net/rniemeyer/9DHHh/1/

Ответ 2

Вы можете использовать синтаксис потока управления без контейнера, который основан на тегах комментариев:

<tbody data-bind="foreach: entries">
    <tr>
        <!-- ko if: type === "file" -->
            <td><i class="icon-file"></i> <a href="#" data-bind="text: name, click: $parent.showFile"></a></td>
        <!-- /ko -->
        <!-- ko if: type !== "file" -->
            <td><i class="icon-folder"></i> <a href="#" data-bind="text: name, click: $parent.goToPath"></a></td>
        <!-- /ko -->
    </tr>
</tbody>