为什么每次进入路线时组件都会自我复制?

时间:2019-04-13 15:05:23

标签: javascript ember.js

我正在开发我的第一个余烬应用程序,但组件遇到问题。我有一条路线可以加载多个组件。每个模型都加载以下范例:

{{#each someList as |item|}}
<MyComponent @item={{item}} />
{{/each

输入路线时效果很好。但是,每次我离开页面并返回而没有刷新时,其中一个组件将再次呈现。

我是Ember的新手。我尝试使用组件生命周期挂钩来强制重新渲染,但没有成功。我也尝试设置一个变量来检查容器是否已经加载,但是在离开页面时会重置。

不起作用:

{{#each this.weapons as |weapon|}}
    <CharacterWeaponDetail @weapon={{weapon}} />
{{/each}}

工作:

{{#each (this.skills) as |skill| }}
    <SkillDetail
    @skill={{skill}} 
    @character={{charactersheet}} 
    @chrSkills={{chrSkills}} 
    @charParam={{charactersheet.id}} 
    @action="filter"
    @unUsedSP={{this.unUsedSP}}
    @realtimeSkillPoints={{realtimeSkillPoints}}
    @filter={{charactersheet.profession.name}}/> 
{{/each}} 

说每个组件加载两次。第一次渲染时,结果如下:

<CharacterWeaponDetail />
<CharacterWeaponDetail />

<SkillDetail />
<SkillDetail />

这是预期的行为。但是,如果我使用{{link-to}}离开路线而没有完全刷新就返回,结果将如下所示:

<CharacterWeaponDetail />
<CharacterWeaponDetail />
<CharacterWeaponDetail />
<CharacterWeaponDetail />

<SkillDetail />
<SkillDetail />

每次页面加载<CharacterWeaponDetail />都会再次重复。我该如何阻止这种情况的发生。

修改

完整路线。

import Route from '@ember/routing/route';
import { hash } from 'rsvp';
import { inject as service } from '@ember/service';
import EmberObject from '@ember/object';

export default Route.extend({
  totalSpSpent: service('total-skill-points-spent'),
  weapons: [],

  async model(params){
    let charactersheet = await this.store.findRecord('charactersheet', params.charactersheet_id );
    let characterWeapons = charactersheet.weaponsets.sets;
    var Weapon = EmberObject.extend({
      fromPlayer: null,
      fromWeapon: null
    });

    for (let i = 0; i < characterWeapons.length; i++) {
      let weapon = Weapon.create();
      let weapons = this.get('weapons');

      let calcWeaponInfo = this.store.findRecord('weapons', characterWeapons[i].weaponID);

      weapon.fromPlayer = characterWeapons[i];
      weapon.fromWeapon = calcWeaponInfo;

      weapons.push(weapon);
      this.set('weapons', weapons);
    }

    return hash({
      charactersheet: charactersheet,
      skills: this.store.findAll('skill'),
      skillcategories: this.store.findAll('skillcategories'),
      skillsubcategories: this.store.findAll('skillsubcategories'),
      chrSkills: [],
      realtimeSkillPoints: null,
      weapons: this.get('weapons')
    })      
  },

  setupController(controller, models){ 
    controller.set('chrSkills', models.chrSkills);
    controller.set('weapons', models.weapons);
    controller.set('realtimeSkillPoints', models.realtimeSkillPoints);
    controller.set('charactersheet', models.charactersheet);
    controller.set('skills', models.skills);
    controller.set('skillcategories', models.skillcategories);
    controller.set('skillsubcategories', models.skillsubcategories);
  },

  afterModel(){
    let totalSpSpent = this.get('totalSpSpent');
    totalSpSpent.clear();
  },
});

根据您的输入,我认为问题是我将武器退还给一个对象,然后将所有对象发送到数组中的组件。随着技能的发展,我将重返余烬。我将其更改并报告。

控制器仅显示页面上的一些模态。

1 个答案:

答案 0 :(得分:2)

每次输入路线时,都会执行路线的model()挂钩。您将在每次执行时创建新的Weapon。这些Weapon对象被推到路由的weapons属性。路由是ember.js中的单例。在每次重新进入路由时,更多的Weapon对象将被推入weapons属性。

您可以通过不将weapons存储为route的属性来解决该错误,而应在每次执行model()钩子时初始化一个新数组。您应该在model钩子中替换此代码

for (let i = 0; i < characterWeapons.length; i++) {
  let weapon = Weapon.create();
  let weapons = this.get('weapons');

  // ...

  weapons.push(weapon);
}

使用

let weapons = [];
for (let i = 0; i < characterWeapons.length; i++) {
  let weapon = Weapon.create();

  // ...

  weapons.push(weapon);
}

您根本不需要在路线上存储weapons。而且您不应该确定每次循环for循环时都应替换该属性。