我正在编写可供用户编辑的阿拉伯语-俄语词典。我遇到了一个我不明白的问题。我正在使用火焰。并且有结构的想法:
<ModalForm>
<ArticleForm>
</ModalForm>
<ArticlePage>
<ArticlesList>
<ArticleSingle><ArticleForm>
</ArticlesList>
</ArticlePage>
打开模态表单ArticleForm
以插入新Article
的,然后将页面重定向到新的ArticlePage
。
ArticlesList
包裹夫妇<ArticleSingle><ArticleForm>
。其中之一是可见的,它取决于editMode
参数。ArticlePage
将数组从一篇文章 ( [articles.findOne]
) 传递到ArticlesList
.
当我添加时,第一篇文章重定向工作正常,并打开一个新页面Article
。只有一个ArticlePage
模板在使用,一个文章实例。重定向从 after-insert-hook (collections-hooks) 开始。
但是当我第二次重复时,出现错误,Exception from Tracker recompute function:
ArticlePage
不渲染,在控制台中我看到两个调用ArticlePage
,第一个是真实数据,第二个是undefined
. 我不明白这篇“未定义”的文章来自哪里。
如果我重新加载该空白页面,它将与新文章一起很好地呈现。
更新:
仅当我尝试从重定向/articles/xxxx
到时才会出现此错误/articles/yyyy
。从主页重定向/
到/articles/xxxx
可以正常工作很多次。
这是它的外观。
代码
组件处理显示情侣 ArticleSingle - ArticleEditForm,用于文章列表(在搜索页面、ActiveCorrections 页面等),以及在 ArticlePage 上,当它只显示一篇文章时,女巫被包装到数组 [Article] 中。
文章页面.html
<template name="ArticlePage">
<div class="container article-page">
<section class="row">
{{#if Template.subscriptionsReady}}
{{> ArticlesList articles=articles}}
{{else}}
<p>Loading...</p>
{{/if}}
</section>
</div>
</template>
文章页面.js
import { Articles } from "/imports/api/articles.js";
Template.ArticlePage.onCreated(function() {
var self = this;
var id = FlowRouter.getParam("id");
self.autorun(function() {
self.subscribe("articleSingle", id);
});
});
Template.ArticlePage.helpers({
articles() {
const id = FlowRouter.getParam("id");
const article = Articles.findOne({ _id: id });
console.log("articlePage article", article);
return [article];
},
isAdmin() {
return Roles.userIsInRole(loggedInUser, ['admin'])
}
});
文章列表.html
<template name="ArticlesList">
<div class="articles-list">
{{#each articles}}
<section class="row">
<div class="col-sm-6 -sticky">
<div class="main-article">
{{> ArticleSingle}}
</div>
</div>
<div class="col-sm-6">
{{#if showEditForm _id}}
{{> ArticleForm }}
{{else}}
{{#each corrections }}
<div class="correction">
{{#if showEditForm _id}}
{{> ArticleForm }}
{{else}}
{{> ArticleSingle }}
{{/if}}
</div>
{{/each}}
{{/if}}
</div>
</section>
{{/each}}
</div>
</template>
文章列表.js
Template.ArticlesList.onCreated(function() {
Session.set("showEditFormForArticle", "");
});
Template.ArticlesList.helpers({
showEditForm(articleId) {
return articleId == Session.get("showEditFormForArticle");
},
corrections() {
if (this.corrections)
return this.corrections.map(elem => {
return { ...elem, _id: elem._id + "-by-" + elem.editedByUserName };
});
else [];
}
});
Template.ArticlesList.events({
"click .correction .btn-success"() {
let doc_id = this._id.split("-")[0];
Meteor.call("articles.accept_correction", doc_id, this);
},
"click .correction .btn-danger"() {
let doc_id = this._id.split("-")[0];
Meteor.call("articles.reject_correction", doc_id, this);
},
"click .main-article .btn-success"() {
let doc_id = this._id.split("-")[0];
Meteor.call("articles.accept", doc_id, this);
},
"click .main-article .btn-danger"() {
let doc_id = this._id.split("-")[0];
Meteor.call("articles.reject", doc_id, this);
}
});
显示字典的单篇文章,包括单词、注释、翻译和示例。
文章单.html
<template name="ArticleSingle">
<div id="article-{{_id}}" class="panel panel-default article {{#if notPublished}}-opacity-06{{/if}}">
<div class="panel-heading">
<div class="panel-title words">
<div class="label label-info speach-part">{{speachPart}}</div>
<!-- Глагол 1й породы имеет дополнительную информацию для вывода, поэтому
особый шаблон его вывода, например, среднекорневую глассную и масдары -->
{{#each words}}
<div class="note">{{note}} </div>
<div class="word -arabic-text-big">{{word}}</div>
<div class="collapse transcription">{{transcr word}}</div>
{{#if isMiddleHarakat ../middleHarakat @index}}
<div class="note middleHaracat" title="среднекорневая гласная настоящего времени">
{{../middleHarakat}}
</div>
{{/if}}
{{/each}}
<button type="button" class="btn btn-default btn-xs btn-transcript"
data-toggle="collapse" data-target="#article-{{_id}} .transcription">
Транскрипция
</button>
</div>
</div>
<div class="panel-body">
<ol class="translations">
{{#each translations}}
<li class="translation">
{{translation}}
{{#if examplesCount examples}}
<a href="" class="showExamplesButton" data-toggle="collapse" title="примеры" data-target=".examples-{{../_id}}-{{@index}}">
<small><i class="glyphicon glyphicon-asterisk"></i>
{{examplesCount examples}}</small>
</a>
<ul class="examples collapse examples-{{../_id}}-{{@index}}">
{{#each examples}}
<li>
<div class="example -arabic-text-mid">{{example}}</div>
<div class="translation">{{translation}}</div>
</li>
{{/each}}
</ul>
{{/if}}
</li>
{{/each}}
</ol>
{{#if image.link}}
<div class="image">
<img class="img-responsive img-rounded" src="{{image.link}}" alt="ArticleImage">
</div>
{{/if}}
<!-- TAGS -->
{{#if tagsRoots}}
<div>
Корень: {{> TagsSelectedSynonyms tags=tagsRoots removeButton=false}}
</div>
{{/if}}
{{#if tagsSubjects}}
<div>
Тематики: {{> TagsSelectedSubjects tags=tagsSubjects removeButton=false}}
</div>
{{/if}}
{{#if tagsSynonyms}}
<div>
Синонимы: {{> TagsSelectedSynonyms tags=tagsSynonyms removeButton=false}}
</div>
{{/if}}
</div>
<div class="panel-footer">
{{> ArticleMenu }}
{{> ArticleCorrectionMenu}}
{{#if showApproveButtons}}
{{> ApproveButtons}}
{{/if}}
</div>
</div>
</template>
ArticleSingle.js
import { Articles } from "/imports/api/articles.js";
import { Subjects } from "/imports/api/subjects.js";
import { transcription, isNotDiacritic } from "/imports/transcription.js";
Template.ArticleSingle.onCreated(function() {
Meteor.subscribe("subjects");
Meteor.subscribe("articlesByIds", this.data.synonyms);
Meteor.subscribe("articlesByIds", this.data.roots);
});
Template.ArticleSingle.helpers({
showApproveButtons() {
return (
Roles.userIsInRole(loggedInUser, ['admin']) &&
this.published === false &&
this.deleted !== true
);
},
notPublished() {
return this.published === false;
},
isMiddleHarakat(middleHarakat, index) {
return middleHarakat && index == 0;
},
rootArticle() {
Meteor.subscribe("articleSingle", this.rootId);
return Articles.findOne({ _id: this.rootId });
},
image() {
const image = Images.findOne({ _id: this.picture });
return image;
},
imageJSON() {
const image = Images.findOne({ _id: this.picture });
image0 = JSON.stringify(image.fetch());
return image0;
},
examplesCount: function(examples) {
return examples.length || 0;
},
transcr: function(text) {
if (text.trim()) return "[ " + transcription(text) + " ]";
},
tagsSubjects() {
const ids = this.subjects;
const tags = [];
let tagsUnordered = Subjects.find({ _id: { $in: ids } }).fetch(); // эта шляпа возвращает массив в смешанном порядке, поэтому их надо заново упорядочить
ids.forEach(tagId => {
tags.push(
tagsUnordered.filter(elem => {
return elem._id == tagId;
})[0]
);
});
return tags;
},
tagsSynonyms() {
const ids = this.synonyms;
const tags = [];
let tagsUnordered = Articles.find({ _id: { $in: ids } }).fetch();
// эта шляпа { $in: ids } возвращает массив в смешанном порядке, поэтому их надо заново упорядочить
ids.forEach(tagId => {
tags.push(
tagsUnordered.filter(elem => {
return elem._id == tagId;
})[0]
);
});
return tags;
},
tagsRoots() {
const ids = this.roots;
const tags = [];
let tagsUnordered = Articles.find({ _id: { $in: ids } }).fetch();
// эта шляпа { $in: ids } возвращает массив в смешанном порядке, поэтому их надо заново упорядочить
ids.forEach(tagId => {
tags.push(
tagsUnordered.filter(elem => {
return elem._id == tagId;
})[0]
);
});
return tags;
}
});
奇怪的是,当我在Template.ArticleSingle.onCreated
console.log(this)中制作时,当我从主页添加文章时/
,重定向后只有一个TemplateInstance,而且渲染得很好。但是当我从页面创建文章时y
,article/x
从现有页面重定向article/x
到新创建的article/y
页面后,控制台中有 3 个 TemplateInstances,其中第三个undefined
。我仍然不明白它出现在哪里:(