是否可以从Ember模板中的HTMLBars异常中恢复?

时间:2016-09-08 19:31:22

标签: ember.js htmlbars

我有一个类似于:

的动态组件
{{component fooProperty owner=this}}

fooProperty是数据驱动的,有时会出错,至少现在是dev,但我担心它也可能在prod中错误地发生(由于应用程序版本控制,持久存储等)。基本上,我不相信这总是正确的(即可以解析为组件)。当值关闭时,整个应用程序崩溃了:

Uncaught Error: Assertion Failed: HTMLBars error: Could not find component named "some-inexisting-component" (no component or template with that name was found)
 EmberError @ ember.debug.js:19700
 assert @ ember.debug.js:6719
 assert @ ember.debug.js:19502
 componentHook @ ember.debug.js:10894
 render @ ember.debug.js:12782
 render @ ember.debug.js:12732
 handleKeyword @ ember.debug.js:46584
 keyword @ ember.debug.js:46709
 exports.default @ ember.debug.js:12483
 handleKeyword @ ember.debug.js:46545
 handleRedirect @ ember.debug.js:46531
...

我更愿意捕获此类异常并阻止整个应用崩溃。我可以想到一个解决方法,例如。审核fooProperty返回App.__container__.lookup并返回通用的“缺失”组件。但是如果可能的话,我仍然希望有一种方法来捕获和处理渲染期间引发的异常。

2 个答案:

答案 0 :(得分:1)

简单的答案是“不,但你可以实现自己的。”模板引擎从未有过异常处理的作用。它不仅与Handlebars / HTMLbars案例相关,而且与JSX,Jinja等其他模板引擎相关,因为异常处理涉及相当多的逻辑,必须在用户端指定,它们似乎不在演示角色的范围内有。其主要原因似乎是Ember Framework开发人员想要强制执行的问题分离,以避免开发人员在他们的应用程序中结束大量额外的意大利面条代码,这可能会大大降低整体代码的可读性和可维护性。

您案件的可能解决方案:

component.js

import Component from 'ember-component';
import get from 'ember-metal/get';
import getOwner from 'ember-owner/get';
import { isEmpty } from 'ember-utils';
import computed from 'ember-computed';

export default Component.extend({
    wantToRenderComponentName: 'name-that-doesnt-exist',
    wantToRenderComponentNameExist: computed('wantToRenderComponentName', {
        get() {
            const owner = getOwner(this);
            return !isEmpty(owner.lookup(`component:${get(this, 'wantToRenderComponentName')}`))
        }
    })    
});

template.hbs

{{#if wantToRenderComponentNameExist}}
    {{component wantToRenderComponentName}}
{{else}}
    // handle your exception presentationally here
{{/if}}

如果组件实例在应用程序中初始化,owner.lookup('component:component-name')将返回组件实例,如果不是,则返回undefined。我可以想象一些情况,如果满足某些条件以节省内存,您可能希望在运行时初始化某些组件,这样就可以检查组件是否在应用程序中初始化并可以在模板中使用。这不是异常处理,因为在此代码中没有引发异常,但是它使用动态组件命名,这就是为什么当您静态指定时,我们可以将对组件存在的实际检查移动到与编译时区分的运行时。要呈现的组件的名称。

答案 1 :(得分:0)

生产版本中不会引发断言错误。所以你的应用程序不会崩溃。如果组件存在,它将呈现,否则它将无声地失败。