2

ビューに移動するたびに更新する必要があるドロップダウン リストを持つウィジェットがあります。ウィジェットが使用されるたびに呼び出される、ウィジェットのビューモデルで使用できるコールバックはありますか? 通常のビューモデルのアクティブ化コールバックとまったく同じように動作するもの。

ウィジェットの activate 関数は、親ビューがロードされるたびに呼び出されるわけではありません:

ctor.prototype.activate = function (settings) {
    this.settings = settings;

};

ただし、ビューが呼び出されるたびに、親ビューモデルの activate 関数が呼び出されます。

    var activate = function (routeData) {
        var id = parseInt(routeData);
        return datacontext.getEntityByID('ProductionRun', id, productionRun)
                          .then(loadProducts)
                          .fail(queryFailed);
    };

loadProducts に関するロジックを親ビューモデルからウィジェットのビューモデルに移動し、ウィジェットのビューで、親のビューモデルではなく、ウィジェットのビューモデルのコレクションを使用したいと考えています。から変更する:

<select data-bind="options: $parent.products, optionsText: 'name', optionsValue: 'productID', value: settings.productionRun().productID"></select>

に:

<select data-bind="options: products, optionsText: 'name', optionsValue: 'productID', value: settings.productionRun().productID"></select>

ありがとう

====== 2013 年 10 月 29 日の更新 ======

App/widgets/productionRunDetails/viewmodel.js のコードは次のとおりです。

define([
    'durandal/app',
    'durandal/composition',
    'messaging',
    'services/datacontext',
    'services/datacontext.product'
], function (app, composition, messaging, datacontext, datacontext_product) {

    function myObject() {
        var productionRunStatuses = ko.observableArray(datacontext.lookups.productionRunStatuses);
        var isSaving = ko.observable(false);
        var hasChanges = ko.computed(function () {
            return datacontext.hasChanges();
        });
        var canSave = ko.computed(function () {
            return hasChanges() && !isSaving();
        });
        var saveProductionRunDetailsCommand = function () {
            isSaving(true);
            return datacontext.saveChanges().fin(complete);

            function complete() {
                isSaving(false);
                app.trigger(messaging.messages.productionRunDetailsWidget_saved, this);
            }
        }
        var cancelProductionRunDetailsCommand = function () {
            datacontext.cancelChanges();
        }

        var closeProductionRunDetailsCommand = function () {
            datacontext.cancelChanges();
        }


        var self = this;
        self.canSave = canSave;
        self.productionRunStatuses = productionRunStatuses;
        self.saveProductionRunDetailsCommand = saveProductionRunDetailsCommand;
        self.cancelProductionRunDetailsCommand = cancelProductionRunDetailsCommand;
        self.closeProductionRunDetailsCommand = closeProductionRunDetailsCommand;
    }

    myObject.prototype.activate = function (settings) {
        this.settings = settings; //This gets called once, during the whole life cycle of the widget
    };


    //myObject.prototype = (function () {
    //    var activate = function () {
    //    };
    //    return {
    //        activate: activate
    //    }
    //})(); // As soon as I add this code (myObject.prototype), the widget does not work.


    var myObj = new myObject();

    return myObj;
});

ウィジェットは、親ビューで次のように実装されています。

<div data-bind="widget: {kind:'productionRunDetails', productionRun:productionRun}"></div>

親ビューからウィジェットに productionRun という ko オブザーバブルを渡しています (ビューモデル内の設定パラメーターで使用できます)。親ビューモデルに読み込まれるウィジェットにドロップダウン リストがあります。ロード操作を親ビューモデルからウィジェットのビューモデルに移動し、バインディングを次のように変更したいと思います。

<select data-bind="options: $parent.products, etc

に:

<select data-bind="options: products

しかし、それを行うには、(親ビューに移動することによって) 親ビューモデルがアクティブになるたびに実行される activate コールバックが必要です。

これは可能ですか?ウィジェットの作成に関するデュランダルの例に従いましたが、アクティブ化コールバックは 1 回だけ呼び出されます ( http://durandaljs.com/documentation/Creating-A-Widget/ )。ホットタオル+デュランダル+ブリーズ初心者です。ありがとうございました。

4

2 に答える 2

0

プロトタイプ パターンの実装方法を再確認する必要があります。

durandal を使用しているので、バインドとアクティベーションが発生するように、公開プロトタイプ パターンを使用する必要があります。

さらに、プロトタイプ化されたメソッドは、バインディングが発生する前にアタッチしてアクセスできるようにするために、自己実行関数内にある必要があります。

ここでは、この例を示します。

function myObject(data){
    var self = this;
    self.prop1 = ko.observable(data.prop1);
    self.prop2 = ko.observable(data.prop2);
    self.joinProps = function(){
        return self.prop1() + self.prop2();
    };
}

myObject.prototype = (function(){
    var activate = function(){
        return this.prop1() + this.prop2();
    };
    return {
        activate: activate,
        joinProps: this.joinProps
    }
})(); // See the () and the end so they get executed. 

プロトタイプにあるように、親オブジェクトメソッドも返すようにしてください。そこに返すと、それで終わりで、プロトタイプ化されたメソッドは添付されません。

最後に、次を使用してこれをテストできます。

var myObj = new myObject({ 'prop1' : 1, 'prop2' : 2 });

ko.applyBindings(myObj);

alert(myObj.joinProps());

durandal のおかげで、applyBindings を呼び出す必要はありません。myObj に相当するものを返すようにしてください。

お役に立てれば

于 2013-10-28T23:29:56.153 に答える
0

前の回答を撤回する必要がありますが、イベントによってウィジェットのすべてのインスタンスが更新されるため、これは良い解決策ではないと思います。似ていますがより良いアイデアは、オブザーバブルを使用してビューを更新することです。あなたの場合、id をオブザーバブルとして渡してサブスクライブすると、id が変更されたときにウィジェットを更新できます。

this.routeData.id.subscribe(function () {
    //refresh data here
});
于 2013-12-24T18:07:10.867 に答える