将viewmodel属性设置为列表中的项目

时间:2014-10-15 13:20:58

标签: javascript html knockout.js

好的,所以我有我的视图模型

function viewModel(calendarData) {
            var self = this;

            self.Calendars = ko.mapping.fromJS(calendarData);
            self.ViewedCalendar = {};//what can/should i set this to be on initial creation?
            self.DisplayCalendar = function (calendar) {
                self.ViewedCalendar = calendar;
            };
        };

然后我有我的HTML:

<div data-bind="visible: Calendars().length > 0">
    <h2>You have <span data-bind="text: Calendars().length"></span> calendars</h2>
    <table class="table">
        <thead>
            <tr>
                <th>Calendars</th>
                <th></th>
                <th></th>
            </tr>
        </thead>
        <tbody data-bind="foreach: Calendars">
            <tr>
                <td data-bind="text: Name"></td>
                <td><span data-bind="text: Events().length"></span> events</td>
                <td><a href='#' data-bind='click: $root.DisplayCalendar'>View</a></td>
            </tr>
        </tbody>
    </table>
</div>

<div data-bind="visible: ViewedCalendar() !== null">
    Your are viewing <span data-bind="text: ViewedCalendar.Name"></span><br />
</div>

我想要实现的是当用户点击给定日历的View时,通过DisplayCalendar()我将属性ViewedCalendar设置为给定的日历。

然后显示我的div,其中包含标明正在查看日历的标签。

这是所有粗略的代码,只是为了获得基本的功能,但我是淘汰赛的新手,所以可以使用一些帮助。

我收到TypeError:ViewedCalendar不是函数,或者ViewedCalendar未定义。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

ViewedCalendar属性需要是一个可观察的淘汰赛才能达到它的价值变化。你这样定义:

self.ViewedCalendar = {};

哪个(空)对象文字而不是函数(正确说明错误消息)。你需要的是:

self.ViewedCalendar = ko.observable();    // empty () give you an empty observable - no calendar selected yet

然后您可以使用以下代码在click处理程序中更新它

self.ViewedCalendar(calendar);

这是一个有效的完整示例:

function viewModel(calendarData) {
            var self = this;

            self.Calendars = ko.mapping.fromJS(calendarData);
            self.ViewedCalendar = ko.observable();
            self.DisplayCalendar = function (calendar) {
                self.ViewedCalendar(calendar);
            };
        };

ko.applyBindings(new viewModel([{Name:'some calendar', Events: []}, {Name:'another calendar', Events: []}]));
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>

<div data-bind="visible: Calendars().length > 0">
    <h2>You have <span data-bind="text: Calendars().length"></span> calendars</h2>
    <table class="table">
        <thead>
            <tr>
                <th>Calendars</th>
                <th></th>
                <th></th>
            </tr>
        </thead>
        <tbody data-bind="foreach: Calendars">
            <tr>
                <td data-bind="text: Name"></td>
                <td><span data-bind="text: Events().length"></span> events</td>
                <td><a href='#' data-bind='click: $root.DisplayCalendar'>View</a></td>
            </tr>
        </tbody>
    </table>
</div>

<div data-bind="with: ViewedCalendar">
    Your are viewing <span style="font-weight: bold" data-bind="text: Name"></span><br />
</div>