3

mvc4用のDurandalスターターテンプレートを使用しています。次の簡単なビューを設定しました。

<section>
    <h2 data-bind="html: displayName"></h2>
     <h3 data-bind="html: posts"></h3>
     <button data-bind="click: getrss">Get Posts</button>
     <div id="rsstestid" ></div>
</section>

およびViewModel:

    define(function (require) {
    var http = require('durandal/http'),
        app = require('durandal/app');

    return {
        displayName: 'This is my RssTest',
        posts: ko.observable(),
        activate: function () {
            return;
        },
        getrss: function () {
            $('#rsstestid').rssfeed('http://feeds.reuters.com/reuters/oddlyEnoughNews');
            return;
        }
    };
});

ご覧のとおり、[投稿を取得]ボタンをクリックすると、zRssReaderプラグインを使用して投稿をdivにロードするだけです。すべてが正常に機能し、表示名が入力され、投稿が期待どおりに表示されます。

私が問題を抱えているのは、ボタンを削除して、作成時に投稿を読み込もうとしたときです。プラグイン呼び出しをアクティブ化関数に配置すると、結果が得られません。これは、ビューが完全にロードされていないため、要素が存在しないためだと思います。2つの質問があります:

  1. ビューが完全に構成されるまでプラグイン呼び出しの実行を遅らせるにはどうすればよいですか?
  2. さらに良いことに、クエリセレクターを使用するのではなく、プラグインの結果を監視可能な投稿にロードするにはどうすればよいですか?私は多くの組み合わせを試しましたが、運がありません

ご協力いただきありがとうございます。

4

4 に答える 4

4

編集**以下の答えはデュランダル1.2用です。デュランダル2.0viewAttachedではに変更されましたattached


durandaljs.comから直接コピーして貼り付けます

「Durandalが作成するときはいつでも、と呼ばれる関数がないかモデルをチェックしますviewAttached。存在する場合は、関数を呼び出し、バインドされたビューをパラメーターとして渡します。これにより、コントローラーまたはプレゼンターはdomサブツリーに直接アクセスできます。親に注入された後のある時点でバインドされます。

注:設定した場合cacheViews:trueviewAttached技術的にはビューが1回だけアタッチされるため、最初のバインド時に、ビューが最初に表示されたときにのみ呼び出されます。この動作をオーバーライドしたい場合はalwaysAttachView:true、コンポジションバインディングを設定してください。」-サイトから引用


あなたがそれをすることができる多くの方法があります、しかしここにただ1つの速くて汚い方法があります:

<section>
    <h2 data-bind="html: displayName"></h2>
     <h3 data-bind="html: posts"></h3>
     <button data-bind="click: getRss">Get Posts</button>
     <div id="rsstestid"></div>
</section>

とコード:

define(function (require) {
    var http = require('durandal/http'),
        app = require('durandal/app');

    var $rsstest;

    return {
        displayName: 'This is my RssTest',
        posts: ko.observable(),
        viewAttached: function(view) {
           $rssTest = $(view).find('#rsstestid');
        },
        getRss: function() {
           $rssTest.rssfeed('http://feeds.reuters.com/reuters/oddlyEnoughNews');
        }
    };
});
于 2013-03-20T00:59:26.593 に答える
2

一般に、ビューモデル内からUI要素に直接触れないようにするのが賢明だと思います。

良いアプローチは、RSSフィードをレンダリングできるカスタムKOバインディングを作成することです。これにより、バインディングの実行時にビューが適切に配置されることが保証されます。ビューモデルのプロパティとしてフィードURLを公開したい場合は、カスタムバインディングが更新時にそれを読み取ることができます。

カスタムバインディングは非常に単純です-私がそれを行うことができれば、それは:)でなければなりません

KnockOutカスタムバインディングクイックスタートへのリンクは次のとおりです:http://knockoutjs.com/documentation/custom-bindings.html

于 2013-03-22T14:30:01.127 に答える
0

私も同じ問題を抱えています。デュランダル ビュー モデルとビューがバインドされた後、要素に直接 css プロパティを設定しようとしています。値を設定している時点でビューが完全に構成されていないため、機能していないと思います。

私が思いついた最善の方法は、デュランダルでviewAttachedライフサイクルイベントを使用することです。これは、デュランダルビューモデルのロードサイクルの最後のイベントであると思います.setTimeoutを使用して、プロパティの設定をさらに遅らせます。

これはかなり面倒な回避策ですが、今のところ機能しています。

   var viewAttached = function (view) {
        var _this = this;

        var picker = new jscolor.color($(view).children('.cp')[0], {
            onImmediateChange: function() {
                _updateCss.call(_this, this.toString());
            }
        });
        picker.fromString(this.color());
        setTimeout(function() {
            _updateCss.call(_this, _this.color());
        }, 1000);
    };

    var activate = function (data) {
        system.log('activated: ' + this.selectors + ' ' + this.color());
    };
    var deactivate = function (isClose) {
        system.log('deactivated, close:' + isClose);
    };

    return {
        viewAttached: viewAttached,
        deactivate: deactivate,
        activate: activate,
        color: this.color
    };
于 2013-03-01T16:13:05.647 に答える