在路由更改上使用过滤器时未渲染路由模型

Posted

技术标签:

【中文标题】在路由更改上使用过滤器时未渲染路由模型【英文标题】:Route model not rendered when using filter on route change 【发布时间】:2017-11-17 11:38:21 【问题描述】:

我正在尝试在新应用上设置 mirage 以进行测试。

ember-cli: 2.16.2

ember-cli-海市蜃楼:0.4.0

我有一个虚拟测试,只是试图设置 mirage 并验证它是否正常工作。 我会做类似于测试route.model() 的事情。 使用 mirage 的JSONAPISerializer,我的工厂和 migrage-model 什么都没有。

// models/trip.js
import DS from 'ember-data';

export default DS.Model.extend(
  name: DS.attr('string'),
);

我的测试:

import moduleFor, test from 'ember-qunit';
import startMirage from 'frontend/initializers/ember-cli-mirage';

moduleFor('route:trips.index', 'Unit | Route | trips.index', 
  needs: ['service:session', 'model:trip', 'adapter:application'],

  beforeEach() 
    this.server = startMirage();
  ,

  afterEach() 
    this.server.shutdown();
  
);

test('model', function (assert) 
  let route = this.subject();

  this.server.create('trip');

  Ember.run(() => 
    this.get('store').findAll('trip')
  );

  assert.ok(route);
);

我收到此错误:

TypeError: Cannot read property 'push' of null
    at Class._setupRelationshipsForModel (http://localhost:4200/assets/vendor.js:196482:36)
    at Class._pushInternalModel (http://localhost:4200/assets/vendor.js:196473:10)
    at http://localhost:4200/assets/vendor.js:196425:20
    at Backburner.run (http://localhost:4200/assets/vendor.js:20213:36)
    at Backburner.join (http://localhost:4200/assets/vendor.js:20222:33)
    at Class._push (http://localhost:4200/assets/vendor.js:196397:50)
    at http://localhost:4200/assets/vendor.js:192955:18
    at tryCatcher (http://localhost:4200/assets/vendor.js:63559:21)
    at invokeCallback (http://localhost:4200/assets/vendor.js:63737:33)
    at publish (http://localhost:4200/assets/vendor.js:63723:9)

在开发/生产和使用真实服务器获取数据方面工作良好。

如果我不使用 mirage 创建我的记录,也不例外。

看起来问题只发生在Ember.run

删除 Ember.run 不会引发异常,但我需要它来正确测试(并避免像 You have turned on testing mode, which disabled the run-loop's autorun. You will need to wrap any code with asynchronous side-effects in a run 这样的错误)...

【问题讨论】:

如果没有Ember.run也不会引发异常,那为什么还要使用呢? 有时我必须使用Ember.run,否则我会收到此错误“您已打开测试模式,这禁用了运行循环的自动运行。您需要将任何具有异步副作用的代码包装在跑步”——这是有道理的。 【参考方案1】:

store.findAll 返回一个承诺。尝试解决承诺并在 .then() 中运行您的断言

(忽略这不是测试路线的方法这一事实,但我知道您只是使用此测试来解决您的 mirage 设置)

【讨论】:

谢谢克里斯托弗,很遗憾这不起作用,请在此处查看建议的解决方案:github.com/samselikoff/ember-cli-mirage/issues/… 你能解释一下为什么这不是对路线进行单元测试的好方法吗?是的,这是一个虚拟示例,但我最后所做的是对路由的模型函数返回正确记录进行单元测试。【参考方案2】:

正如@rstellar 在此处https://github.com/samselikoff/ember-cli-mirage/issues/1220#issuecomment-350155703 所建议的那样,一个可行的解决方案是在函数周围使用 async/await。

当我们在 store 被销毁后尝试建立关系时会发生此问题。此解决方案将防止这种情况发生,直到函数结束。

这是工作代码:

import moduleFor, test from 'ember-qunit';
import wait from 'ember-test-helpers/wait'; // import wait from ember here
import startMirage from 'frontend/initializers/ember-cli-mirage';

moduleFor('route:trips.index', 'Unit | Route | trips.index', 
  needs: ['service:session', 'model:trip', 'adapter:application'],

  beforeEach() 
    this.server = startMirage();
  ,

  afterEach() 
    this.server.shutdown();
  
);

test('model', async function (assert)  // Declare this function as async 
  let route = this.subject();

  this.server.create('trip');

  Ember.run(() => 
    this.get('store').findAll('trip')
  );

  assert.ok(route);

  await wait(); // The actual wait
);

在 Ember 上打开了一个 PR,以使错误更加明确。

【讨论】:

以上是关于在路由更改上使用过滤器时未渲染路由模型的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 4 过滤不同角色的组路由

vue - 过滤器-钩子函数路由

如何使 IRouteConstraint 过滤路由

ngmodel 更改时未触发角度日期过滤器

如何在 react 中的新路由更改上使用 useEffect 重新渲染变量

ASP.NET Core使用功能开关控制路由访问(续)