AngularJS无法读取未定义的属性'childNodes'错误。

4
现在在Angular代码的一个子函数中的compileNodes函数中,有以下这些行:
} else if (childLinkFn) {
  childLinkFn(scope, node.childNodes, undefined, boundTranscludeFn);
}

在我的自定义选项卡指令中,当我尝试使用以下代码手动编译指令的模板(为了在选项卡上动态添加点击功能)时,出现错误:无法读取未定义的属性“childNodes”:
```javascript $templateRequest('tabs.html').then(function(html){ var template = angular.element(html); $compile(template)(scope); element.append(template); }); ```
nucleusAngular.directive('nagTabs', ['$timeout', '$http', '$compile', 'nagDefaults', function($timeout, $http, $compile, nagDefaults){
    return {
        restrict: 'A',
    scope: {
      options: '=nagTabs'
    },
        compile: function() {
            return {
                pre: function(scope, element, attributes) {
                    var template = $('<div />').append($(element).html());
                    scope.options = nagDefaults.getTabsOptions(scope.options);

                    template.find('.tabs .tab').each(function(key, value) {
                        template.find('.tabs .tab:nth-child(' + (key + 1) + ')').attr('ng-click', 'switchTab(\'' + $(this).data('tab') + '\')');
                    });

                    element.html($compile(template)(scope));
                    $(element).addClass('nag-tabs');
                },
                post: function(scope, element, attributes) {
                    var $element = $(element);
                    scope.switchTab = function(tab) {
                        if(angular.isNumber(tab)) {
                            //todo: this should work
                            //tab = $(element).find('.tabs li:nth-child(' + tab + ')').data('tab');
                            tab = $(element).find('.tabs .tab:nth-child(' + (tab + 1) + ')').data('tab');
                    }

                        $(element).find('.tabs .tab').removeClass('active');
                        $(element).find('.tabs .tab[data-tab="' + tab + '"]').addClass('active');

                        $(element).find('.tab-content-item').removeClass('active');
                        $(element).find('.tab-content-item[data-tab="' + tab + '"]').addClass('active');
                    }

                    //load the default tab
                    $timeout(function(){scope.switchTab(scope.options.defaultTab);}, 0);
                }
            };
        }
    }
}]);

HTML:

<div nag-tabs="tabsOptions">
    <ul class="tabs">
        <li data-tab="html" ng-click="switchTab('html')">HTML</li>
        <li data-tab="javascript" ng-click="switchTab('javascript')">JavaScript</li>
    </ul>
    <div class="tab-content">
        <div data-tab="html" class="tab-content-item">
            html...
        </div>
        <div data-tab="javascript" class="tab-content-item">
            javascript...
        </div>
    </div>
</div>

现在也许我没有正确编译模板,但我已经尝试了我能想到的每一种方式来编译模板,但我要么得到上述错误,要么功能根本不起作用。阅读周围的内容后,似乎这个错误可能是由于存在空文本节点而引起的。由于我已经尝试了我代码中能想到的所有方法,所以我进入了Angular代码并修改了三行代码,使其看起来像这样(我只修改了第一行):

} else if (childLinkFn && node) {
  childLinkFn(scope, node.childNodes, undefined, boundTranscludeFn);
}

这将验证节点是否实际存在,以确定是否调用childLinkFn函数(虽然我不能百分百确保更改的影响,但似乎如果节点不等于某个值,则不应执行childLinkFn)。通过使用此代码,我的选项卡代码完美地工作(我没有注意到其他指令中的任何其他问题)。然后,我克隆了angular.js存储库并应用了此更改,构建了angular,然后执行了单元测试和端到端测试,所有测试都通过了。

我的问题是,我在编译选项卡模板时是否做错了什么,或者我应该将此代码更改提交为拉取请求(请注意,我正在使用1.1.3版本)?


错误是在IE还是Chrome还是所有浏览器中发生的? 另外,标签看起来像什么?您需要发布适用的整个代码或发布JSFiddle。 - Ketan
已添加所请求的代码,错误在所有浏览器中发生,而我的 Angular 代码没有任何更改。当我对 Angular 代码进行更改时,在所有浏览器中都可以正常工作。 - ryanzec
最好在“pre”中进行编译并添加处理程序和操作,在“post”中进行操作。尝试将HTML字符串直接传递到$compile中。创建一个实时演示。 - charlietfl
@charlietfl:在进行$compile之前,我会在pre中添加事件处理程序,因为在模板编译后无法添加ng-click事件(而且在AngularJS中使用类似jQuery事件似乎是逆向思维)。 - ryanzec
@charlietfl:添加元素不是问题,问题在于添加 ng-click 属性。据我所知,让指令正常工作(如ng-click)的唯一方法是将它们放入传递给 $compile 的 html 中。当我尝试在 $compile 后只添加 ng-click 属性时,单击这些元素没有任何反应。 - ryanzec
显示剩余2条评论
1个回答

1
最终,我已经更改了指令的格式。不确定它是如何工作的,返回带有pre/post对象的指令并不能实现,但是它确实有效。指令代码现在看起来像这样:
nucleusAngular.directive('nagTabs', ['$timeout', '$http', '$compile', 'nagDefaults', function($timeout, $http, $compile, nagDefaults){
return {
    restrict: 'A',
scope: {
  options: '=nagTabs'
},
    compile: function(element, attributes, transclude) {
  $(element).find('.tabs .tab').each(function(key, value) {
    $(element).find('.tabs .tab:nth-child(' + (key + 1) + ')').attr('ng-click', 'switchTab(\'' + $(this).data('tab') + '\')');
  });

  //element.html($compile(template)(scope));
  $(element).addClass('nag-tabs');

return function(scope, element, attributes) {
    scope.options = nagDefaults.getTabsOptions(scope.options);
    var $element = $(element);
    scope.switchTab = function(tab) {
      if(angular.isNumber(tab)) {
        //todo: this should work
        //tab = $(element).find('.tabs li:nth-child(' + tab + ')').data('tab');
        tab = $(element).find('.tabs .tab:nth-child(' + (tab + 1) + ')').data('tab');
      }

      $(element).find('.tabs .tab').removeClass('active');
      $(element).find('.tabs .tab[data-tab="' + tab + '"]').addClass('active');

      $(element).find('.tab-content-item').removeClass('active');
      $(element).find('.tab-content-item[data-tab="' + tab + '"]').addClass('active');
    }

    //load the default tab
    $timeout(function(){scope.switchTab(scope.options.defaultTab);}, 0);
        }
    }
}
}]);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接