检测observableArray

时间:2017-06-29 19:14:35

标签: javascript typescript knockout.js

在淘汰赛文档中有一段说你可以用属性作为observables创建一个observableArray,但是没有一个例子: http://knockoutjs.com/documentation/observableArrays.html

所以我想要实现的是向observableArray添加一个元素,该元素具有observable属性,以便在单击时检测状态更改。所以这是我到目前为止的代码

export class Team {
        Name: KnockoutObservable<string>;
        Score: KnockoutObservable<number>;
        ListTeamsArray: KnockoutObservableArray<any>;
        selectedTeam: KnockoutObservable<boolean>;

        constructor(json) {
            var self = this;

            if (json !== null) {
                self.Name = ko.observable(json.Name);
                self.Score = ko.observable(0);
                self.ListTeamsArray = ko.observableArray();
                self.selectedTeam = ko.observable(false);
            }
        }

        addTeam = () => {
            var self = this;
            //Working correctly and I'm declaring "selectedTeam" as an observable with initial value of "false"
            var newTeam = { Name: self.Name(), Score: 0, selectedTeam: ko.observable(false)};
            self.ListTeamsArray.push(newTeam);
        }

        //Here I create a function that is passing a "team" parameter (the one in the array and it's working fine
        teamSelectedFn = (team: Team, event) => {
            var self = this;
            $(".teamPanel").css("background", "none");

            //Loop thru array in knockout to assign selected value, probably there's a better way
            ko.utils.arrayForEach(self.ListTeamsArray(), (item) => {
                if (item.Name === team.Name) {
                    $(event.currentTarget).css("background", "#a4e4ce");
                    item.selectedTeam = ko.observable(true);
                } else {
                    item.selectedTeam = ko.observable(false);
                }
            });

            //just for testing
            ko.utils.arrayForEach(self.ListTeamsArray(), (item) => {
                console.log(item);
                console.log(item.selectedTeam());
            });
        }
    }

这是HTML

<div class="row" id="teamCrud">
    <div class="col-sm-3" >
        <div class="form-group">
            <input class="form-control" data-bind="value: Name" />
            @*<span data-bind="text: Score"></span>*@
            <button data-bind="click: addTeam" class="btn btn-success">Add</button>
        </div>
    </div>
    <div class="col-sm-9">
        Equipos
        <div data-bind="foreach: ListTeamsArray" class="row">
            <div class="col-sm-3">
                <div class="panel panel-default teamPanel" data-bind="click: $parent.teamSelectedFn, style: { border: selectedTeam() ? '2px solid red' : 'none'}@*, style: { background: $data.selectedTeam() ? 'red' : 'none'}*@">
                    <div class="panel-heading" data-bind="text: Name"></div>
                    <div class="panel-body">
                        Score:
                        <p data-bind="text: Score"></p>
                        Seleccino
                        <p data-bind="text: selectedTeam()"></p>
                    </div>
                </div>

            </div>
        </div>
    </div>
</div>

它正在工作的一切,我知道我可以使用knockout更改HTML元素的背景颜色,但我需要检测依赖项更改。它没有检测到数组中可观察对象的变化。还有其他我需要做的事情或者我是以错误的方式处理这个问题吗?

1 个答案:

答案 0 :(得分:2)

在您的单击函数中,您将使用新的observable覆盖绑定的observable。您可能只需要更改函数来更新现有的observable而不是替换它。

teamSelectedFn = (team: Team, event) => {
    var self = this;
    $(".teamPanel").css("background", "none");

    //Loop thru array in knockout to assign selected value, probably there's a better way
    ko.utils.arrayForEach(self.ListTeamsArray(), (item) => {
        if (item.Name === team.Name) {
            $(event.currentTarget).css("background", "#a4e4ce");
            item.selectedTeam(true);
        } else {
            item.selectedTeam(false);
        }
    });