“不能对不在DOM中的Metamorph执行操作” - 仅在< = IE8中

时间:2012-05-23 19:19:19

标签: ember.js

使用Ember 0.9.7.1

当我的应用启动并输入第一个状态时,在IE8及以下版本中出现此错误。我有一个相当大的应用程序,所以我不确定我可以在jsFiddle中重现,但我会尝试显示下面的相关位。

我在GitHub上看过这些类似的问题,但我认为两者都没有描述我做错了什么(它是我的......对吗?))

https://github.com/emberjs/ember.js/issues/752
https://github.com/emberjs/ember.js/issues/447

我的应用程序的初始视图由状态管理器创建/加载,如下所示:

SYOS.stateManager = Em.StateManager.create({

    enableLogging: true,
    rootElement: #syos-root,
    initialState: 'noSectionSelected',

    noSectionSelected: Ember.ViewState.create({

        view: SYOS.SelectSectionView,

        chooseSection: function (manager, context) {

            manager.goToState('sectionSelected');

        }

    }),
<snip>

该视图基本上定义为:

SYOS.SelectSectionView = Em.View.extend({

templateName: 'selectSectionView',
sectionsBinding: 'SYOS.sectionController.sections'
});

模板的精简版本如下所示:

<script type="text/x-handlebars" data-template-name="selectSectionView">

<h2>Some markup</h2>

<table class="select-sect" cellspacing="0">
{{#each sections}}
    {{#view SYOS.SelectSectionRowView sectionBinding="this" tagName="tr"}}
    <td class="sect">{{section.name}}</td>
    {{/view}}
{{/each}}
</table>

</script>

如果有帮助的话,这个模板直接在我的html中定义。

当我加载页面时,控制台日志显示:

LOG: STATEMANAGER: Entering noSectionSelected 
SCRIPT438: Object doesn't support this property or method 
ember-0.9.7.1.min.js, line 10 character 30680
SCRIPT5022: Cannot perform operations on a Metamorph that is not in the DOM. 
ember-0.9.7.1.min.js, line 13 character 29412
SCRIPT5022: Exception thrown and not caught 
ember-0.9.7.1.min.js, line 13 character 16607

使用IE的调试器(eww)打破第一个错误,我可以看到#each变形标记的错误似乎。它打破了这一行:

g.prototype.checkRemoved=function(){if(this.isRemoved())throw new Error("Cannot perform operations on a Metamorph that is not in the DOM.")}

因为this.isRemoved()返回true。检查调试器中的this我看到this.start ==“metamorph-6-start”。如果我在工作浏览器中搜索该变形标记,它似乎是我模板中#each块的开始标记。

sectionsBinding是一个从jQuery .ajax调用加载的数组,所以最初它会是[]然后使用this.get('sections').pushObject(section);填充,同时在我的控制器中循环ajax调用的结果。

我没有在此状态下执行任何动态视图追加或删除,只需加载视图并在从ajax服务调用返回时绑定这些部分。

有人可以指出我在这个问题上的正确方向吗?谢谢!

编辑:更新为Ember 0.9.8.1,现在控制台中的错误少了一点:

LOG: STATEMANAGER: Entering noSectionSelected 
SCRIPT5022: Cannot perform operations on a Metamorph that is not in the DOM. 
ember-0.9.8.1.min.js, line 14 character 4051
SCRIPT438: Object doesn't support this property or method 
ember-0.9.8.1.min.js, line 10 character 31677

4 个答案:

答案 0 :(得分:11)

对此进行跟进,让任何googlers在那里解决这个问题。

简而言之 - 我通过完全重新审视我们的观点以及如何将其添加到应用中来解决这个问题。

我想强烈建议任何使用Ember应用程序遇到奇怪的人使用Ember的Debug版本运行他们的应用程序。控制台中提供的断言和反馈非常宝贵。

我实际上有两个问题在进行:

1)在构建上表的#each中,我使用了另一个#each,其中我使用了绑定的把手助手(在http://codebrief.com/2012/03/eight-ember-dot-js-gotchas-with-workarounds/找到并且非常非常有用)。

由于嵌套得如此之深,我不得不使用{{ boundHelper this}}来调用我的绑定助手,这似乎真的让人感觉不舒服。 Chrome,Firefox和IE9似乎并没有因此而窒息 - 不确定原因。但基本上使用带有this的绑定帮助程序最终将''传递给normalizePath,并导致此断言失败

function normalizePath(path) {
  Ember.assert('must pass non-empty string to normalizePath()', path && path!=='');

我通过将boundHelper更改为值数组或单个值来解决此问题,因此我可以将其写为{{boundHelper colors}}并在我的帮助器中循环而不是使用#each。< / p>

2)所以,一个问题下来,但仍然得到原始的变形错误。清除了另一个错误后,我现在可以告诉变形错误完全来自另一个视图。

我有两个使用#view帮助器在我的HTML中定义的嵌套视图。不知何故,嵌套视图导致父级重新渲染。同样,Ember的调试版本是一个很好的工具来跟踪它,因为它在控制台中记录了一条消息。

我不是百分之百确定为什么这是一个这样的问题,但似乎在重新渲染过程中,变形标签不存在并且它会引发一个问题。这看起来似乎可能是Ember中的一个错误,但更可能的是我只是没有采取“Ember方式”。和Ember一样好,也很容易射击你的脚:))

我最终将这些内联视图添加到Handlebars模板中,并将视图附加到Ember App.ready函数中的DOM。这清除了所有错误和IE 7&amp; 8现在可以无误地呈现应用程序。

答案 1 :(得分:7)

当我在HTML评论中发现一些把手代码时,我刚刚解决了这个问题。违规代码可能刚被移除或包装在手柄评论中,如下所示:

{{!--
    <h1>{{myTitle}}</h1>
--}}

答案 2 :(得分:5)

我遇到了这个问题,因为我们试图这样做:

<input size="16" type="text" valueBinding="{{deadline}}">

实际上应该是:

<input size="16" type="text" {{bindAttr valueBinding="deadline"}}>

答案 3 :(得分:0)

我今天刚刚遇到这个问题,并希望我的经验会帮助别人。我们看到了相同的错误消息,在删除所有注释掉的车把代码后,将此引用更改为显式的#each对象名称,没有任何效果。

事实证明,如果多次嵌入#with和#each,视图会有点不稳定:

{{#with view.content.project as project}}
    //set some project fields
    {{#each job in project.jobs}}
        {{#with job}}
            // set job some fields
        {{#/with}}
        {{#each task in job.tasks}}
            {{#with task}}
                // set tasksome fields
            {{#/with}}
        {{/each}}
    {{/each}}
{{/with}}

我们发现,如果我们在第一个#each之前使用(#with view.content.project作为项目)关闭项目,那么错误就会消失。我不确定为什么这是一个问题,但是,这可能会帮助其他人解决同样的问题。

有效的代码:

{{#with view.content.project as project}}
    //set some project fields
{{/with}}
{{#each job in project.jobs}}
    {{#with job}}
        // set job some fields
    {{#/with}}
    {{#each task in job.tasks}}
        {{#with task}}
            // set tasksome fields
        {{#/with}}
    {{/each}}
{{/each}}