You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ember对象状态泄漏错误:排序属性数组定义合规性咨询

Fixing "Only string, number, symbol, boolean, null, undefined, and function are allowed as default properties" in Ember Controller

Let's fix that ESLint error in your Ember controller! The issue here is that you've defined sortedProperties as a plain array directly on the controller's default properties, which violates the ember/avoid-leaking-state-in-ember-objects rule.

Why this happens

Ember shares default reference-type properties (like arrays or objects) across all instances of a class. That means if one instance modifies sortedProperties, every other instance of this controller would see that change too—this is called state leakage, and it's the exact problem the rule is trying to prevent. The rule only allows primitive values (strings, numbers, booleans, etc.) or functions as default properties because those don't carry shared state risks.

Solution 1: Use a function to return the array

Since functions are allowed as default properties, you can rewrite sortedProperties to return a new array each time an instance is created. This ensures every controller instance gets its own independent copy of the array:

import Controller from "@ember/controller";
import { computed } from "@ember/object";

export default Controller.extend({
  filter: "",
  filterTodos: computed("arrangedContent", "filter", function() {
    var filter = this.get("filter");
    var rx = new RegExp(filter, "gi");
    var todos = this.model;
    return todos.filter(function(todo) {
      return todo.get("title").match(rx) || todo.get("body").match(rx);
    });
  }),
  // Return a fresh array via a function to avoid shared state
  sortedProperties: () => ["date:asc"],
  sortedTodos: computed.sort("model", "sortedProperties")
});

If you ever need access to the controller instance (this) in the property (you don't here, but just in case), use a regular function instead of an arrow function:

sortedProperties: function() {
  return ["date:asc"];
}.property(),

Solution 2: Initialize the property in the init method

Another reliable approach is to set sortedProperties inside the controller's init hook. This guarantees the array is created when the instance initializes, avoiding shared state:

import Controller from "@ember/controller";
import { computed } from "@ember/object";

export default Controller.extend({
  filter: "",
  filterTodos: computed("arrangedContent", "filter", function() {
    var filter = this.get("filter");
    var rx = new RegExp(filter, "gi");
    var todos = this.model;
    return todos.filter(function(todo) {
      return todo.get("title").match(rx) || todo.get("body").match(rx);
    });
  }),
  sortedTodos: computed.sort("model", "sortedProperties"),

  init() {
    this._super(...arguments); // Always call the parent class's init method first
    this.set("sortedProperties", ["date:asc"]);
  }
});

Which solution to choose?

  • Use Solution 1 for simple, static default values—it's concise and straightforward.
  • Use Solution 2 if you need more complex initialization logic (like conditionally setting the sorted properties based on other data).

内容的提问来源于stack exchange,提问作者Abbas Ghaith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:40:54