gpt4 book ai didi

ember.js - 路由转换会破坏渲染的 View 对象; "Error: Object in path [blah] could not be found or was destroyed."

转载 作者:行者123 更新时间:2023-12-04 12:32:58 26 4
gpt4 key购买 nike

从一个 Ember 路由转换到另一个路由时,我收到以下错误:

Error: Object in path item_delet could not be found or was destroyed.

在 route ' renderTemplate钩子(Hook),我正在做很多这样的事情:
this.render('item_delete', { into: 'item_parent', outlet: 'item_delete' });

...并有一个合理的父/子模板树。然而,当一个模板,比如“item_delete”,被渲染成一个“routeA”,然后我点击进入“routeB”,然后回到“routeA”,我得到了错误。我知道当路由器退出“routeA”以防止内存泄漏时, View 对象正在被破坏。我不确定为什么重新输入路由不会重新创建/实例化/连接 View 。附带说明一下,当出现错误时,任何先前呈现的收到此错误消息的 View 总是将其路径名缩短一个字符,请注意“item_delet”而不是“item_delete”。

我正在使用 grunt-ember-templates 来编译 Handlebars 模板,因此发布 JSFiddle 有点困难。只是想知道是否有人可以“查看”此代码来标记路线或 renderTemplate 的任何明显原因。钩子(Hook)可能无法重新实例化/连接/等。渲染的模板。我可以做一些“激活/停用”魔法来防止 View 被破坏吗? (我意识到这与破坏 View 对象背后的意图背道而驰,但我愿意听取所有选择。)

我有一个 Ember 路线图,如下所示:
App.Router.map(function () {

this.route('index', { path: '/projects' });
this.resource('items', { path: '/projects/folders' }, function() {
this.resource('item', { path: '/:item_id' }, function() {
this.route('file_uploads', { path: '/file_upload' });
});
});

});

我有这样定义的路线:
App.IndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('items');
}
});

App.ItemsIndexRoute = Ember.Route.extend({

model: function() {
// Setting up the model
}
, setupController: function(controller, model) {
// Setting up some controllers
}
, renderTemplate: function() {
this.render('index', {
into: 'application'
, outlet: 'application'
, controller: this.controllerFor('items')
});

this.render('navbar', {
into: 'application'
, outlet: 'navbar'
, controller: this.controllerFor('currentUser')
});

this.render('items', {
into: 'index'
, outlet: 'index'
, controller: this.controllerFor('items')
});

this.render('items_toolbar', {
into: 'index'
, outlet: 'items_toolbar'
, controller: this.controllerFor('items')
});

this.render('item_rename', {
into: 'items_toolbar'
, outlet: 'item_rename'
, controller: this.controllerFor('items')
});

this.render('item_delete', {
into: 'items_toolbar'
, outlet: 'item_delete'
, controller: this.controllerFor('items')
});

// ... some more of these...

}

});

App.ItemRoute = Ember.Route.extend({

model: function (params) {
// Building the model for the route
}
, setupController: function(controller, model) {
// Setting up some controllers
}
, renderTemplate: function() {
this.render('index', {
into: 'application'
, outlet: 'application'
, controller: this.controllerFor('items')
});

this.render('navbar', {
outlet: 'navbar'
, into: 'application'
, controller: this.controllerFor('application')
});

this.render('items', {
into: 'index'
, outlet: 'index'
, controller: this.controllerFor('items')
});

this.render('items_toolbar', {
into: 'index'
, outlet: 'items_toolbar'
, controller: this.controllerFor('items')
});

this.render('item_rename', {
into: 'items_toolbar'
, outlet: 'item_rename'
, controller: this.controllerFor('items')
});

this.render('item_delete', {
into: 'items_toolbar'
, outlet: 'item_delete'
, controller: this.controllerFor('items')
});

// ... some more of these...

}

});

App.ItemFileUploadsRoute = Ember.Route.extend({

model: function() {
// Setting up the model
}

, setupController: function(controller, model) {
// Setting up some controllers
}

, renderTemplate: function() {

this.render('file_uploads', {
into: 'application'
, outlet: 'application'
, controller: this.controllerFor('fileUploads')
});

this.render('navbar', {
into: 'application'
, outlet: 'navbar'
, controller: this.controllerFor('application')
});

this.render('items_toolbar', {
into: 'file_uploads'
, outlet: 'items_toolbar'
, controller: this.controllerFor('fileUploads')
});

this.render('item_rename', {
into: 'items_toolbar'
, outlet: 'item_rename'
, controller: this.controllerFor('items')
});

this.render('item_delete', {
into: 'items_toolbar'
, outlet: 'item_delete'
, controller: this.controllerFor('items')
});

// ... some more of these...
}

});

我正在为不同的路线/资源重用一些模板及其导出。例如,上面提到的“items_toolbar”在 Handlebars 模板中,如下所示:
<div class="row toolbar">
<div class="col col-lg-6 text-right">
{{outlet submission_options_button}}
{{outlet submission_button}}
{{outlet create_button}}
{{outlet confirm_button}}
{{outlet cancel_button}}
{{outlet folder_actions}}
{{outlet item_rename}}
{{outlet item_delete}}
</div>
</div>

在这个模板中,并不是所有的 outlet 都会得到一个渲染到它们中的缓冲区,而在其他上下文中它们会。我这样做是为了避免 Handlebars 代码中不受欢迎的(令人困惑的)条件(以及通常的“isVisible”废话)。我对给定的模板感兴趣,根据需要“佩戴”它的 View ;在某些情况下,可能有“create_button”和“cancel_button”,而在其他情况下,可能有“cancel_button”和“folder_actions”。

是否有任何可靠的方法来确保在重新进入路线时,之前在其中渲染、然后销毁的任何对象都可以重新连接、重新初始化和/或重新渲染?

最佳答案

有兴趣的可以继续关注。事实证明,在我的方法中(过度)使用 {{outlet}} ——更不用说在路由器中将模板渲染到它们中——是一种反模式。

在与 Tilde 的帮派进行了多次讨论后(感谢@peterwagenet,@codeofficer),我学会了“Ember 方式”来做我正在尝试的事情是使用 Ember 提供的生成的路由和 Controller 并使用 {{view}} 助手直接在 Handlebars 模板中渲染 View 对象。

所以,在我上面的例子中, App.ItemsIndexRoute.renderTemplate() 中应该没有任何东西,并且模板中的 {{outlet}} s 应该为零。命名为 {{outlets}} 用于渲染当前路由“外部”的路由,典型示例是模态,可能与 socket 正在渲染的父路由具有不同的模型。例如:

<div>
{{view App.UsersListView}}
{{outlet order_books_from_mars_modal}}
</div>

我所拥有的 App.Router.map() 中的路线非常正确,尽管我对生成的 Controller 有一些很大的误解。当你有一个 App.FooRoute 时,Ember 会设置一个 App.FooController ,它应该在应用程序代码的某个地方定义。无论您在路线的 App.FooController 钩子(Hook)中提供什么,该 model 都可以作为其模型,例如:
App.FooRoute = Ember.Route.extend({

model: function() {
return $.get('/some/resource', function() { ... });
}

});

App.FooRoute 内呈现的所有 View 提供的 Controller 是 App.FooController ,它具有早先在路由的 model Hook 中提供的模型。

并且路由器将寻找匹配路由和 Controller 前缀的 Ember.View 对象,例如 App.FooView 。所以,当有类似的事情时:
App.FooView = Ember.View.extend({

template: 'some-foo-template'

});

...与 App.FooController 匹配的路由将呈现 App.FooView 以及 View 的 template 属性中指示的模板。就像是:
<script type="text/x-handlebars" data-template-name="some-foo-template">
<div class="row toolbar">
<div class="col col-lg-6 text-right">
{{view App.SubmissionButtonView}}
</div>
</div>
</script>

在这个 View 中,一个 App.SubmissionButtonView 正在使用 {{view}} 助手渲染。所以,需要有一个对应的:
App.SubmissionButtonView = Ember.View.extend({

template: 'the-killer-button'

});

...模板将类似于:
<script type="text/x-handlebars" data-template-name="the-killer-button">
<a {{action someControllerMethod}}>Do Something</a>
</script>

预计 someControllerMethod 将在 App.FooController 上找到。如果在 Controller 上没有找到, Action 将冒泡到 App.FooRouteevents 对象。如果在链上的任何对象上都没有找到该方法,则会记录一个错误,指示没有处理 someControllerMethod 操作。

因此, App.FooController 将默认提供给 App.SubmissionButtonView ,因为它在 App.FooRoute 内呈现。但是,您可以通过执行以下操作将不同的 Controller 绑定(bind)到它——例如, App.BarController:
{{view App.SubmissionButtonView controllerBinding='App.BarController'}}

在这种情况下,预计将在 someControllerMethod 或前面提到的 App.BarController 上找到 App.FooRoute

类(class)?

在所有这一切结束时,对我来说,教训实际上是关于正确建立路由层次结构,利用 Ember 提供的生成 Controller ,并使用 {{view}} 助手而不是像我一开始尝试的那样使用命名的 {{outlet}} 来渲染 View 。 Ember 期望命名路由具有相应的 Controller 和相应的 View 。一旦我明白了这一点,这一切对我来说就开始更好地结合在一起了。

在我的情况下,现在因为嵌套资源都处理适本地渲染它们的 subview ——当用户导航“离开”当前路线时销毁它们,当用户在当前资源/路线“内”导航时保留它们——我发布的原始错误不再发生。

与往常一样,Embering yourself silly 的最佳资源是 Ember Guides

关于ember.js - 路由转换会破坏渲染的 View 对象; "Error: Object in path [blah] could not be found or was destroyed.",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17263446/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com