1

Flask と Knockoutjs を使用してプロジェクトを作成しています。ノックアウトを使用してコメントを表示しています。コメント投稿者の名前の下にも表示されます。クリックすると、そのユーザー プロファイルが表示されます。

ここにコードがあります

<a data-bind="attr: { href: '{{ url_for('user_profile')}}' + '/' + name() + '/' + uid() + '/'  }"><p data-bind="text: name"></p></a>

しかし、上記のコードでは、Jinja2 Template エラーが発生します。

BuildError: ('user_profile', {}, None)

そこで、ノックアウト属性のドキュメントを参照する上記のコードを変更しましたKnockout attr binding

<a data-bind="attr: { href: '{{ url_for('user_profile')}}', name: name , uid: uid  }"><p data-bind="text: name"></p></a>

しかし、同じエラー

BuildError: ('user_profile', {}, None)

これは、user_profile ビューが必要な変数を取得していないことを意味します。ノックアウトでは、これを行う方法は attr バインディングです。この質問を参照しました

Jinja2: Flask's url_for() と Knockout's attr binding の組み合わせ

しかし、期待どおりに機能するものは何もありません

4

4 に答える 4

1

問題は、データとテンプレート情報の分離だと思います。

ノックアウトを使用している場合、通常はサーバーでデータを生成し、クライアント側でレンダリングするテンプレートに json データとして送信します。

このurl_for関数はサーバー側の 関数であるため、クライアント側のテンプレート内でクライアント上で実行することはできません。

@Miguelの回答のように、最も簡単で最良の方法は、テンプレートの一部としてではなく、データの一部としてサーバー上でURLを生成することです。

したがって、データを生成するための app.route は次のようになります。

@app.route('/posts/')
def posts_list():
    posts = []
    for post in get_posts():  #however you actually get your posts from your db
        author = get_author(post.author)  #however you actually get author info

        posts.append(
            {"id": post.id,
             "title":post.title,
             "author_name": author["display_name"],
             "author_uri":  url_for('user_profile', author["name"], author["id"]),
             "content": post.content})
    return jsonify({"posts": posts})

または何でも。サーバー側ですべての投稿データを生成しているので、url_for 関数にアクセスできます。その後、クライアントは純粋なデータのみをレンダリングする必要があります。

<div data-bind="foreach: posts">
  <div class="post">
    <div data-bind="text: content" class="content"></div>
    <div class="author_info">
      <a data-bind="attr: { href: author_uri }, text: author_name"></a>
    </div>
  </div>
</div> <!-- posts -->

次に、HTML の app.route で、純粋なノックアウト テンプレートをすべて作成した後、ノックアウト ビューを初期化し、posts json ルートからデータを要求します。

<!-- at the end of your HTML page/view, after including your models, and libs -->
<script type="text/javascript">
    // autogenerated:
    POSTS_URL="{{ url_for('posts_list') }}";

    // initialise views:
    postsview = new PostsView( data );
    ko.applyBindings(posts);

    // get initial data:
    $.getJSON(POSTS_URL, function (data) {
        // we've just got data sent to us from the posts_list route!
        postsview.posts(data.posts);
    });

</script>

jinja テンプレート コード (サーバー側) とノックアウト テンプレート コード (クライアント側) を混ぜようとすると、問題が発生します。それらを完全に別個のシステムとして扱い、純粋なデータ (通常は JSON) をやり取りする必要があります。

別の方法として、別の非同期リクエストを作成するのではなく、データをページに直接埋め込むこともできます。ただし、もう一度、ノックアウト コードを jinja テンプレートから完全に解放することを忘れないでください。次に、ページの最後で、$.getJSON を実行する代わりに、次のようにします。

<script type="text/javascript">
    POSTS_DATA={{ posts |tojson|safe }};
    posts = new PostsView( POSTS_DATA );
    ko.applyBindings(posts);
</script>

このようにデータを分離すると、推論がはるかに簡単になります。また、後で別の JavaScript エンジンに切り替えることにした場合でも、データには必要なものがすべて含まれているため、そうすることができます。または、Python エンジンを書き直すことにした場合、またはネイティブ アプリを作成したい場合などです。

これが役立つことを願っています!

于 2013-11-10T14:32:17.917 に答える
0

私は Knockout の経験があまりありませんが、user_profile を引用符で囲むのは正しくないように思えます。url_for 関数のパラメーターで引用符文字をエスケープしてみてください。

<a data-bind="attr: { href: '{{ url_for(\'user_profile\')}}', name: name , uid: uid  }"><p data-bind="text: name"></p></a>  

お役に立てば幸いです。

よろしくお願いします

于 2013-11-05T09:10:49.690 に答える