Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/409.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Mithril-在子组件修改父组件数据后重新排序子组件数组_Javascript_Sorting_Data Binding_2 Way Object Databinding_Mithril.js - Fatal编程技术网

Javascript Mithril-在子组件修改父组件数据后重新排序子组件数组

Javascript Mithril-在子组件修改父组件数据后重新排序子组件数组,javascript,sorting,data-binding,2-way-object-databinding,mithril.js,Javascript,Sorting,Data Binding,2 Way Object Databinding,Mithril.js,如果有人能为这个问题想出一个更好的标题,请让我知道 我花了很长时间才找到这个问题的答案。我相信其他人也会犯同样的错误,所以我会把答案贴在下面 一旦我提供了一些背景信息,这个问题就更有意义了。我有一个父组件,它有一个带有匹配键的对象数组(例如,ctrl.arrayOfObjects)。我根据每个对象共享的一个键的值对该数组进行排序(例如,ctrl.arrayOfObjects[0].keyToSortBy)。然后,我将现在排序的数组中的每个元素传递给另一个组件 此子组件有一个onclick方法,用

如果有人能为这个问题想出一个更好的标题,请让我知道

我花了很长时间才找到这个问题的答案。我相信其他人也会犯同样的错误,所以我会把答案贴在下面

一旦我提供了一些背景信息,这个问题就更有意义了。我有一个父组件,它有一个带有匹配键的对象数组(例如,
ctrl.arrayOfObjects
)。我根据每个对象共享的一个键的值对该数组进行排序(例如,
ctrl.arrayOfObjects[0].keyToSortBy
)。然后,我将现在排序的数组中的每个元素传递给另一个组件

此子组件有一个
onclick
方法,用于更改父级和子级之间共享的数据,即父级的
ctrl.arrayOfObjects
中的一个对象。它更改了用于对父组件的
ctrl.arrayOfObjects
进行排序的键的值(例如
sharedObject.keyToSortBy

我的问题是,在触发此
onclick
事件后,父组件不会对对象数组重新排序。
onclick
事件确实修改了它应该修改的数据(
sharedObject.keyToSortBy
),我知道这是因为页面确实重新呈现了
sharedObject.keyToSortBy
的新值。但它不会重新排序父组件的
ctrl.arrayOfObjects

奇怪的是,如果我执行
console.log
,会调用sort方法,但页面不会显示任何更改

下面是代码的样子(
ctrl.arrayOfObjects
ctrl.jones
):


如何分离这些组件并使这种重新排序方法仍能工作?

解决方案很简单。在父组件和子组件之间共享对象时,将对象传递给子组件的
视图
方法,而不是
控制器
方法

在Mithril中创建组件时,可以将数据传递给组件的
控制器
视图
方法。该数据将是
控制器
方法的第一个参数和
视图
方法的第二个参数

不要将共享对象设置为
JokeWidget
controller
方法内部的
ctrl.joke
,然后在其
view
方法内部引用它,只需将共享对象直接传递给
view
方法即可。像这样:

var JokeWidgetSeries = {
  controller: function() {
    var ctrl = this;
    ctrl.jokes = [{
      text: "I'm a joke",
      votes: 3
    }, {
      text: "This is another joke",
      votes: 1
    }, {
      text: "A third joke",
      votes: 1
    }]
  },
  view: function(ctrl) {
    return m('#jokes-container',
      m('#jokes',
        ctrl.jokes.sort(function(a, b) {
          // Sort by number of votes.
          return (a.votes < b.votes) ? 1 : (a.votes > b.votes) ? -1 : 0;
        }).map(function(joke) {
          // Create a 'JokeWidget' component instance for each object in 'ctrl.jokes'.
          // Share the 'joke' object with the child component.
          return m('.joke', [
            m('.joke-text', joke.text),
            m('.joke-vote-count', joke.votes),
            m('.thumb-up', {
              onclick: function(e) {
                // Here, the array of 'JokeWidget' DOM elements
                //   DO re-sort. Why?
                joke.votes += 1;
              }
            })
          ]);
        })
      )
    );
  }
};
var JokeWidget = {
  // Do not pass the object this way.
  // controller: function(joke) {
  //   var ctrl = this;
  //   ctrl.joke = joke;
  // },
  // Pass the shared object as a second parameter to the 'view' method.
  view: function(ctrl, joke) {
    return m('.joke', [
      m('.joke-text', joke.text),
      m('.joke-vote-count', joke.votes),
      m('.thumb-up', {
        onclick: function(e) {
          // Now, the array of 'JokeWidget' DOM elements will re-sort.
          joke.votes += 1;
        }
      })
    ]);
  }
};
这也消除了额外的抽象层,使其更易于阅读和理解

var JokeWidget = {
  // Do not pass the object this way.
  // controller: function(joke) {
  //   var ctrl = this;
  //   ctrl.joke = joke;
  // },
  // Pass the shared object as a second parameter to the 'view' method.
  view: function(ctrl, joke) {
    return m('.joke', [
      m('.joke-text', joke.text),
      m('.joke-vote-count', joke.votes),
      m('.thumb-up', {
        onclick: function(e) {
          // Now, the array of 'JokeWidget' DOM elements will re-sort.
          joke.votes += 1;
        }
      })
    ]);
  }
};