3

現在、meteorセッションと、コードがテンプレートをレンダリングするためにどのようにトリガーするかについて問題があります。現在、._idをクリックされたものに設定するセッションがあります。

Template.sidebar.events({
/* on click of current sidecat class change to sidecat selected */
'click .sidecat': function (event) {
    Session.set("selected_project", this._id);
    }
});

そして、selected_playerがdivと等しい場合は、cssクラスを追加します。

Template.sidebar.sidebarselected = function () {
   return Session.equals("selected_project", this._id) ? "sidebarselected" : '';
}

サイドバーが選択されていて、別のクラスが存在する場合に、テンプレートをレンダリングします。アイテムをクリックすると、テンプレートがレンダリングされます。

Template.sidebar.projectselected = function() {
var find = Session.get("selected_project");
var find2 = ($("#"+find).attr('class'));
/* if exists return true render the template */
if (find2 == 'project sidebarselected')
{
  return  true
}
/* else don't render it return null */
else {
  return null
}
};

これまでのすべてがうまく機能します。これで、リストに新しいアイテムを作成し、それを選択したアイテムにするボタンができました。トラブルが発生したときです。新しいアイテムを作成すると、リストアイテムがレンダリングされ、クラスサイドバーが選択されますが、呼び出されるテンプレートがレンダリングされません。アイテムをクリックすると、テンプレートがレンダリングされます。ただし、ボタンを使用して新しいリストアイテムを作成する場合は除きます。選択されますが、テンプレートはレンダリングされません。これがそのためのコードです。

Template.sidebar.events({
/* add bar settings menu functions for clicks */
'click #newProject': function(event){ 
  var create = NewProject();
  Session.set("selected_project", create);
},

これはNewProject関数です

/* add a new project to the side bar */
function NewProject() {
id = Aprojects.insert({
  name: "New Project",
  type: "project"
});
doc = Aprojects.findOne({_id:id});
return doc._id;
}

OK、すべてあります。ボタンをクリックするとアイテムが作成され、クラスは追加されますが、テンプレートはレンダリングされません。これがすべてのjavascriptです。htmlが必要な場合はお知らせください。提供します。

詳細とhtmlテンプレートのものを追加しましょう。しかしとにかく、何が機能するのか

  • リストからプロジェクトを選択できます
  • プロジェクトを(クリックして)選択すると、選択されたことを示すクラス名が付けられます
  • 「新しいプロジェクト」をクリックすると、リストにアイテムを追加してすぐに選択します

それはすべて正しく機能します。問題は、新しいプロジェクトボタンをクリックするときです。それでも、新しく作成されたプロジェクトが適切に選択され、選択されたクラスが与えられます。選択されたbarクラスにもプロジェクトのクラスがあることがわかった場合は発生しません。別のテンプレート(projectpicked)をレンダリングします。Projectpickedは、アイテムがクリックされたときに表示されます。#newprojectがクリックされたときではありません。選択されたとしても、projectpickedテンプレートは表示されません。コードがもっと話をすることができるかどうか見てみましょう。

<body>
{{> sidebar}}
</body>
<template name="sidebar">
{{#if aproject}}
  {{#each aproject}}
    <div class="sidecat {{sidebarselected}} project" id="{{divids}}">
    {{name}}
    </div>
  {{/each}}
{{/if}}
{{#if projectselected}}
{{> projectpicked}}
{{/if}}
</template>

<template name="projectpicked">
project was picked from sidebar
</template>

アプリケーションロジックとDOM構造の組み合わせの背後にある理由は、カテゴリのようなプロジェクト以外にも他のものがあるということです。セッションを使用してIDを取得し、それがプロジェクトまたはカテゴリのようなクラスであるかを判断し、それがどのクラスであるかに基づいて異なるテンプレートを表示することを考えました。それが最善の方法かどうかはわかりませんが、それが私が思いついた方法です。提案を受け入れます。不明な点がある場合は、私にはわかりません。説明しようと思います。助けてくれてありがとう。

4

2 に答える 2

2

ヘルパーを書き直して、projectselectedそのロジックを実行するためにHTMLクラス名に依存するのではなく、Session値に依存するようにします。ほとんどのコードで正しく使用Sessionしていますが、アプリケーションロジックをDOM構造に結合するのは奇妙に思えます。

現時点でのコードの動作(HTMLテンプレートは表示されません。投稿する必要があります)では、次のようになります。

  • リストからプロジェクトを選択できます
  • プロジェクトを(クリックして)選択すると、選択されたことを示すクラス名が付けられます
  • 「新しいプロジェクト」をクリックすると、リストにアイテムを追加してすぐに選択します

そのシナリオを解決する方法は次のとおりです。

テンプレート

<body>
 {{> sidebar}}
</body>

<template name="sidebar">
  <ul>
    {{#each items}}
    <li class="{{selected}} project" id="id_{{_id}}">{{_id}}</li>
    {{/each}}
    {{> newproject}}
  </ul>
  {{> projectpicked}}
</template>

<template name="newproject">
    <li id="newproject">Create a new project</li>
</template>

<template name="projectpicked">
  {{#if projectpicked}}
    A project was picked!
  {{/if}}
</template>

あなたのJavaScript

// When clicking an item in the list, remember which one we just clicked
Template.sidebar.events({
  "click li": function() {
    Session.set("selected_project", this._id);
  }
});

// Add the selected class to the item that was remembered
// by the session when we clicked on it
Template.sidebar.selected = function() {
  return Session.equals("selected_project", this._id) ? "selected" : "";
}

Template.sidebar.items = function() {
  // or whatever code you have to return the list of items
  return Projects.find(); 
}

// when clicking the new project button, create the new project
// and remember the id, then store that as the selected value in the session.
Template.newproject.events({
  "click #newproject": function() {
    var newprojectId = newProject(); // do your thing
    Session.set("selected_project", newprojectId);
  }
});

Template.projectpicked.projectpicked = function() {
  return !Session.equals("selected_project", undefined);
}

ここで重要なのは、何かをクリックしたときにのみselected_projectセッション値を設定することです。それは2回起こります。アイテムをクリックして選択したとき、および新しいプロジェクトをクリックしたとき。

テンプレートで選択したアイテムを描画するには、Meteorで行う必要があるのは、アイテムが選択されたときの記述だけです。あるセッション値がそのIDと一致したときにアイテムが選択されます。それで全部です。

私はこのコードをテストしておらず、明らかに不完全ですが、コードを少しリファクタリングするための正しい方向を示していることを願っています。

于 2013-02-27T01:46:50.047 に答える
0

まあ、かなりイライラしてコードの大部分をもう一度書き直した後、私は問題を見つけました。私のprojectpickedテンプレートでは、Session.getを使用してから、それを使用してクラスを検索する代わりに。代わりに私はただ持っています

if ($('.sidecat.project').hasClass('sidebarselected')) {
return true
}

オリジナルは:

if (find2 == 'project sidebarselected')
{
return  true
}

そのため、変数find2を文字列と直接比較する代わりに、jqueryを使用しました。

于 2013-03-01T17:20:46.770 に答える