Ember: 修改路径中的模型

Ember: modify model in a route

我正在开发 Ember 应用程序,但遇到了问题。我必须在应用程序的某个点过滤掉结果,比如在控制器或视图中,如下所示:

view.hbs 我将在 {{#if test.passed}}... 取消通过的测试:

{{#each tests as |test|}}<br>
    {{#if test.passed}}
        {{test.name}}
    {{/if}}
{{/each}}

我可以在最初加载并可以在输入字段中过滤掉的控制器上执行此操作:

import Controller from '@ember/controller';
export default Controller.extend({
    actions: {
        filterByTest: function (param) {
            if (param !== '') {
                return this.get('store').query('test', { name: param }).then((filteredTests) => {
                    return { query: param, tests: filteredTests.filterBy('passed', true) };
                });
            } else {
                return this.get('store').findAll('test').then((tests) => {
                    return { query: param, tests: tests.filterBy('passed', true) };
                });
            }
        }
    }
});

现在我需要在 route 级别过滤掉。 route 中的 model() 无法编辑,如果可以,则它必须是路径,我不想要。我怎样才能做到这一点?如何使模型可编辑?目前我可以进入路线模型,但无法编辑。这是我与 view.hbs 文件中的模型对话的方式,它有效。

{{#each model as |test|}}<br>
    {{test.name}}
{{/each}}

请参阅下方 returns 文件到上述 view.hbs 模板的模型。同样,它正在运行:

import Route from '@ember/routing/route';

export default Route.extend({
    model() {
        return this.get('store').findAll('test').then(tests => {
            return tests('passed', true);
        })
    }
});

如何将参数传递给模型并对其进行编辑,以便我的 UI 也发生变化?

这是我需要修改的模型。目前 return 有效,但不可修改。

这有点猜测,因为我不是 100% 确定你想要实现什么。

我不知道 param 从何而来,但我假设有一个类似 yourroute?name=TestName 的查询参数。有了这个,您可以像这样访问该参数:

export default Route.extend({
  // if you leave that out, it'll work for the first entry, but the model will not update if you transitionToRoute with only the queryParams changed)
  queryParams: {
    category: {
      refreshModel: true
    }
  },

  model(params) {
    // params has format of { name: "TestName" }
    return this.get('store').query('test', params);

    // you can of course put more complex logic in here, as you had it in controller
    // f.e.: 
    // return this.get('store').query('test', {name: params.name, passed: true});
    // or check first if you have a param at all...
  }
}

here's the docs.

注:
您不能在控制器上设置参数来更改模型。我已经试过了...deperately.
要更改它,您必须在模板中执行 {{link-to "routeName" (query-params name="newName")}} 或在控制器中执行 transitionToRoute({ queryParams: { name: 'anotherName' } }); (docs for transitionToRoute())。

旁注:将filterByTest作为一个动作无论如何都很奇怪。这应该是计算出来的 属性.

如果我的理解与@Jeff 相同,您想根据用户通过按钮或某种方式选择的选项来查询您的后端。这方面最好从状态上考虑。控制器将有一个状态,表示您要表示的过滤器视图,您的 model() 挂钩将使用该状态来了解如何查询您要显示的特定模型集。

这是一个演示这是如何完成的工作技巧(后端使用 ember-cli-mirage):https://ember-twiddle.com/150708278ceafc6f9f99961122a14f07

重点是我的路由定义了一个 queryParams 对象(与@Jeff 的回答相同),它指示路由在控制器上每次 category 属性 时刷新其模型变化。

queryParams: {
  category: { refreshModel: true }
},

model() 挂钩中,我使用 params.category 值来构建正确的查询负载。

model(params) {
  if (params.category === 'all') {
    return this.store.findAll('test');
  }
  let passed = params.category === 'passed';
  return this.store.query('test', { 'filter[passed]': passed });
}

最后我确保我的控制器知道 category 是由 URL:

驱动的
queryParams: ['category'],
// A default is required to train ember on how to serialize
// the value in the URL
category: 'all',

您现在可以更改 category 值,整个路线将自动为您刷新,或者您可以使用 link-to 帮助程序

<button {{action (mut category) "passed"}}>Show passed</button>
{{#link-to "index" (query-params category="passed")}}Show passed{{/link-to}}

你好@AmazingDayToday 我将对我们如何看待你的问题以及我们将如何根据可用信息解决它进行更详细的解释。看起来 @Jeff 已经回答了你,但希望这能帮助你更多地了解如何思考这些问题。

我们的第一个假设是您希望将过滤器参数作为操作的一部分传递。在测试这个时,我们创建了一系列按钮,将 name 属性传递给操作,如下所示

<button {{action 'filterByTestName' 'face'}}>Face</button>
<button {{action 'filterByTestName' 'first test'}}>First Test</button>
<button {{action 'filterByTestName' ''}}>Clear</button>

最后一个按钮旨在利用相同的操作来清除过滤器。在这些情况下,我通常倾向于创建一个单独的 clear 操作,但它现在有效

我实现这类过滤器的主要方法之一是在控制器上为相关路由计算 filteredModel 属性。这个计算的 属性 的要点是基于控制器上的 "filterValue" 进行过滤,可以通过 filterByTestName 操作设置。让我们从这里开始:

actions: {
  filterByTestName: function(name) {
    this.set('filterValue', name);
  }
}

此操作的设计是为了在设置 filterValue 时,我们然后根据该值过滤模型。让我们继续计算 属性,它将为我们做过滤器:

filteredModel: Ember.computed('filterValue', 'model.@each.name', function() {
  if(Ember.isEmpty(this.get('filterValue'))) {
    return this.model;
  }

  return this.model.filter((test) => test.get('name') === this.get('filterValue'));
}),

在计算 属性 上您会注意到的第一件事是我们有两个 依赖键 即这个计算 属性 将在 filterValue 或任何模型上的任何 name 值发生变化。

此实现中要注意的第二件事是 "base case",当 filterValue 为空时,我们希望通过 不修改 来传递当前模型。

此实现的最后一部分是我们要根据 filterValue.

的当前值在当前模型上实际执行过滤器

您可以看到整个示例都在处理此 Ember Twiddle and you can see us solving this problem live on this YouTube video

希望对您有所帮助