【问题标题】:Is it possible to recover from HTMLBars exception in Ember template?是否可以从 Ember 模板中的 HTMLBars 异常中恢复?
【发布时间】:2017-01-16 20:27:06
【问题描述】:

我有一个类似的动态组件:

{{component fooProperty owner=this}}

fooProperty 是数据驱动的,有时会错误地关闭,至少现在在开发中是这样,但我担心它也可能在 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
...

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

【问题讨论】:

    标签: ember.js htmlbars


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      您的情况可能的解决方案:

      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')}`))
              }
          })    
      });
      

      模板.hbs

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

      owner.lookup('component:component-name') 将返回一个组件实例,如果它在应用程序中被初始化,或者undefined 如果不是。我可以想象在某些情况下,如果满足某些条件以节省内存,您可能希望在运行时初始化某些组件,因此这是检查组件是否在应用程序中初始化并且可以在模板中使用的方法。这不是异常处理,因为此代码中没有引发异常,但它使用动态组件命名,这就是为什么当您静态指定要渲染的组件的名称。

      【讨论】:

        猜你喜欢
        • 2015-07-30
        • 2016-09-17
        • 2016-03-16
        • 1970-01-01
        • 1970-01-01
        • 2020-08-11
        • 1970-01-01
        • 2016-07-02
        • 2011-08-19
        相关资源
        最近更新 更多