Ractive 创建重复的 "ghost" 组件,但不显示或调用生命周期事件

Ractive creating duplicate "ghost" components, but not displaying or calling lifecycle events

我对这个已经束手无策了。

本质上,Ractive 是创建一个组件的两个实例,但只调用其中一个的 oninit——实际上不在 DOM 中的那个。在导航到另一个 "page" (main.set('page', 'somepage')) 然后导航回上一页后会发生这种情况。

主要的ractive实例非常简单:

var main = new Ractive({
  el: 'main',
  template: require('templates/main'),
  partials: partials,
  components: { ... },
  data: {
    loading: true,
    page: 'loading',
    component: function(name){
        if (!!this.partials[name]) return name;
        this.partials[name] = '<' + name + '/>';
        return name;
    },
  },
});

及其模板:

{{> navigation}}

<div id='page'>
    {{> component(page) }}
</div>

{{> footer}}

我尝试在 Plunkr 中复制它,但没有成功。相反,我将调试器语句添加到实时的未压缩版本中。

编辑:删除了实时版本

导航回索引页后发生。打开控制台。单击右上角的 'login' 按钮,然后单击徽标返回索引。有源地图,感兴趣的文件是 homepage.js('ghosted' 的组件)和 router.js(主要实例所在的位置)。

看起来路由器正在从注册路由的第一个组件调用注册函数:

oninit: function() {

    // self out here has new guid 
    var self = this;

    route('/', getFeatured, getTrending);

    function getFeatured(context, next) {
        // self in here has "r-1"
        next();
    ...            

好像page.js没有注销的概念。一种方案是将路由注册移至根组件,路由移至子组件:

// in root:
route('/', function(){ 
    this.findComponent('homepage').getFeatured()
}, function(){ 
    this.findComponent('homepage').getTrending()
}

// in homepage component, add as methods:
getFeatured: function(context, next){
    ...
},
getTrending: function(context, next){
    ...
},

Marty 的洞察力让我看到了哪里出了问题,所以他得到了公认的答案,但这是我对问题的解决方案。

我创建了一个提供 route 函数的子类,该函数将任何路由的函数包装在回调中,将它们重新绑定到当前组件。它确实假设了一些我试图避免的全局范围,但在这种情况下是一个必要的邪恶。

//Controller.js
module.exports = Ractive.extend({

    route: function(path, fn) {

        var self = this;

        var fns = [].slice.call(arguments, 1).map(function(fn) {

            return function() {

                // assumes `main` is global — the root Ractive instance of your app
                self = main.findComponent(self.component.name)
                fn.apply(self, arguments);
            }

        });

        // also assumes `page` is a global
        page.apply(this, [path].concat(fns));

    }

});

对于组件:

return Controller.extend({

    ... 

    oninit: function() {

        this.route('/', getFeatured, getTrending);

        //the `this` in `getFeatured()` will now be the correct instance

    },

    ... 

});

}