3

サブスクリプションを起動せずに監視可能なプロパティを設定するにはどうすればよいですか?

ページが読み込まれ、データを取得するために ajax 呼び出しが行われ、データがループされ、現在選択されているアイテムがオブザーバブルに設定されるというシナリオがあります。このオブザーバブルが初めて設定されたときは初期状態と見なされ、サブスクリプションは初期状態で実行されるべきではないため、サブスクリプションを起動せずにこのオブザーバブルを設定できるようにしたいと考えています。

function PlanViewModel() {
    var self = this;

    self.plans = ko.observableArray();
    self.selectedItem = ko.observable();

    self.getAllPlans = function () {
        $.ajax({
            url: "/Backoffice/Home/GetAllPlans",
            type: "POST",
            data: {},
            context: this,
            success: function (result) {
                var planList = this.plans;
                // clear the plan list
                planList.removeAll();
                $.each(result.plans, function () {
                    var planDetail = new PlanDetail(this, self);
                    if (this.IsSelected) {
                        self.selectedItem(planDetail); // how do I set this without the subscriptions firing?
                    }
                    planList.push(planDetail);
                });
            },
            error: function (result) {
                alert("An error occured getting plans.");
            }
        });
    }

    self.selectedItem.subscribe(function (newItem) {
        newItem.repositoryUpdateSelectedPlan();
    } .bind(self));
}
4

2 に答える 2

5

次のようにコードを再構築できます。

function PlanViewModel() {
    var self = this;

    self.plans = ko.observableArray();

    self.getAllPlans = function () {
        $.ajax({
            // …
            success: function (result) {
                // …
                $.each(result.plans, function () {
                    var planDetail = new PlanDetail(this, self);
                    if (this.IsSelected) {
                        self.selectedItem = ko.observable(planDetail);
                    }
                    planList.push(planDetail);
                });
                if (self.selectedItem === undefined) { 
                    self.selectedItem = ko.observable(); 
                }
                self.selectedItem.subscribe(function (newItem) {
                    newItem.repositoryUpdateSelectedPlan();
                }.bind(self));
            },
            // …
        });
    }
}

つまり 、目的の初期状態が達成された後にのみ Knockout を開始します。

于 2012-07-01T14:33:22.647 に答える
-1

ありがとう、私はそのルートをたどり、いくつかの変更を加えて作業しました。selectedItem オブザーバブルは、最初からモデルで定義する必要があります。これは、バインディングで使用されているためです。ただし、提案したようにサブスクリプション部分を移動しましたが、うまくいきました。

function PlanViewModel() {
    var self = this;

    var selectedItemSubscription = null;

    self.plans = ko.observableArray();
    self.selectedItem = ko.observable();

    self.getAllPlans = function () {
        $.ajax({
            url: "/Backoffice/Home/GetAllPlans",
            type: "POST",
            data: {},
            context: this,
            success: function (result) {
                var planList = this.plans;
                // clear the plan list
                planList.removeAll();
                $.each(result.plans, function () {
                    var planDetail = new PlanDetail(this, self);
                    if (this.IsSelected) {
                        if (selectedItemSubscription != null)
                            selectedItemSubscription.dispose();

                        self.selectedItem(planDetail);
                    }
                    planList.push(planDetail);
                });

                selectedItemSubscription = self.selectedItem.subscribe(function (newItem) {
                    newItem.repositoryUpdateSelectedPlan();
                }.bind(self));
            },
            error: function (result) {
                alert("An error occured getting plans.");
            }
        });
    }
}
于 2012-07-01T15:25:33.397 に答える