ember.js 将自定义变量添加到EmberRouter,然后在另一个文件中使用它

9rbhqvlz  于 2022-11-05  发布在  其他
关注(0)|答案(1)|浏览(93)

我最近尝试扩展EmberRouter以包含以下信息。

路由器.js

import EmberRouter from '@ember/routing/router';

const Router = EmberRouter.extend({
  lastVisitedURL: null,

  init() {
    this._super(...arguments);
    this.on('routeWillChange', () => {
      this._super(...arguments);
      this.lastVisitedURL = this.currentURL;
    });
  }

  // Router.map code (not important)
})

现在我想从一个控制器文件中提取lastVisitedURL。但是,我不知道该怎么做。我尝试过的一些方法包括直接导入EmberRouter(即):

import Router from '../router';

export default Controller.extend({
   someFunction() {
     console.log(Router.lastVisitedURL); // returns undefined
   }
});

我不完全确定这种方法的问题是什么,但它似乎返回了某种其他对象或函数,而这些对象或函数并不真正包含路由器的状态。
因此,下一种方法(似乎更容易被接受)是尝试使用RouterService对象,我认为该对象旨在为EmberRouter提供API。

import Router from '../router';

export default Controller.extend({
   router: service(),

   someFunction() {
     console.log(this.router.lastVisitedURL) // returns undefined
   }
});

这个解决方案遇到的问题是,尽管routerService可以存储EmberRouter的状态,但它不能存储我的特定新变量。因此,我现在需要一种方法来将这一特定的数据块添加到RouterService和EmberRouter中。
我真的不知道如何做到这一点,或者是否有一个更好的方法来解决我试图解决的问题。任何想法感谢!

5jdjgkvh

5jdjgkvh1#

老实说,我对你的用例有点困惑。当前的URL在RouterService上可用,默认情况下,它是Ember附带的。你可以这样访问它:

import Controller from '@ember/controller';
import { inject as service } from '@ember/service';

export default Controller.extend({
   router: service(),

   someFunction() {
     console.log(this.router.currentURL);
   }
});

看起来你是想重新发明这个功能。
如果你想在EmberRouter示例上声明一个属性,并在其他地方使用它,你需要在容器上查找路由器。它以router:main的形式提供。你不能直接导入它,因为它既不是服务也不是控制器。代码如下所示:

import Controller from '@ember/controller';
import { getOwner } from '@ember/application';

export default Controller.extend({
   someFunction() {
     let owner = getOwner(this);
     let router = owner.lookup('router:main');
     console.log(router.currentURL);
   }
});

我不会推荐这样的模式。我不认为它是官方支持的。据我所知,router:main是私有API。所以它可能会在一个次要版本中被打破。
通过一项服务可以更好地解决这一问题:

// app/services/location-history.js

import Service from '@ember/service';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';

export default Service.extend({
  router: service(),

  updateRoute: action(function() {
    this.visitedURLs = [...this.visitedRoutes, this.router.currentURL];
  }),

  init() {
    this.router.on('routeDidChange', this.updateRoute);
    this.set('visitedURLs', []);
  },

  willDestroy() {
    this.router.off('routeDidChange', this.updateRoute);
  }
});

如果您发现该语法难以阅读,我建议切换到原生ECMAScript类,这是Ember Octance:

// app/services/location-history.js

import Service from '@ember/service';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';

export default class LocationHistoryService extends Service {
  @service router;

  visitedURLs = [];

  @action
  updateRoute() {
    this.visitedURLs = [...this.visitedRoutes, this.router.currentURL];
  }

  constructor() {
    this.router.on('routeDidChange', this.updateRoute);
  },

  willDestroy() {
    this.router.off('routeDidChange', this.updateRoute);
  }
});

相关问题