0

我正在尝试使用 AngularJS 的 ng-repeat 指令显示一组数据。此 html 代码在同一个控制器下工作,并且具有与constants变量更新异步相同的范围:

 <div class="popup3" id="constant_insert">
        <h2>Insert constant</h2>
        <select id="constants" ng-model="clonedModel.category" ng-options="c.name for c     in constants"></select>
        <div ng-repeat="c in constants">
            <input type="radio" ng-model="model.selected" ng-value="c"/> {{ c.name }}     <br/>
        </div>
        <div style="clear: both; height: 20px;"></div>
        <div id="confirm" class="save_button">Insert</div>
        <div id="cancel" class="save_button">Cancel</div>
    </div>

ng-options 适用于我的数据并显示constants但 ng-repeat 的内容不是。

生成的 HTML 是这样的:

<div class="popup3 ng-scope visible" id="constant_insert">
        <h2>Insert constant</h2>
        <select id="categories" ng-model="clonedModel.category" ng-options="c.name for     c in constants" class="ng-pristine ng-valid"><option value="?" selected="selected">    </option><option value="0">aa</option><option value="1">ee</option></select>
        <!-- ngRepeat: c in constants -->
        <div style="clear: both; height: 20px;"></div>
        <div id="confirm" class="save_button">Insert</div>
        <div id="cancel" class="save_button">Cancel</div>
    </div>

是的,数据来自异步调用,并且这个 html 通过 transclude 指令从模板生成,但就 ng-options 显示数据而言,所有这些通常的范围。$apply 的东西已经完成,在我看来它与问题无关,所以我省略了所有这些代码。问题是 - 为什么 ng-repeat 不能与能够使用的数据 ng-options 一起使用?ng-repeat 有什么特别之处?有什么我需要知道的问题吗?Ofc 如果我用这个 html 模板制作一个简单的控制器,那么这两个指令都可以工作。但我试图找到一个错误,它隐藏在这些指令如何处理数据的差异中。

谢谢!

PS:指令:

.directive('modalDialog', function ($compile, $http, Notification) {
        return {
            restrict: 'A',
            transclude: true,
            replace: false,
            scope: {
                confirm: '&',
                cancel: '&',
                init: '&',
                model: '='
            },
            link: function postLink(scope, element, attrs) {
                app.log('modal link');
                //clone model
                scope.clonedModel = {};
                scope.isNew = attrs.creating ? true : false;
                app._clone(scope.model, scope.clonedModel, false);
                var modal = $('<div class="overlay"></div>');
                modal.attr('id', scope.$id);
                var dialog;
                var _dialog;
                if (attrs.templateId) {
                    dialog = $('#' + attrs.templateId).clone();
                    bind();
                } else if (attrs.partialName) {
                    $http.get('partials/' + attrs.partialName + '.html', {cache: true}).then(function (response) {
                        modal.html(response.data);
                        dialog = modal.children();
                        bind();
                    });
                }
                function closeDialog(button) {
                    app.log('modal close');
                    button.off('click');
                    modal.removeClass('visible');
                    _dialog.removeClass('visible');
                    scope.$apply(function () {
                        scope.cancel()
                    });
                }
                function bindConfirm(button) {
                    app.log('bind confirm');
                    button.on('click', function () {
                        app.log('clear bind confirm');
                        button.off('click');
                        app._clone(scope.clonedModel, scope.model, false);
                        scope.confirm({model: scope.model, isNew: scope.isNew}).then(function () {
                            app.log('dialog scope confirm');
                            //succeeded
                            modal.removeClass('visible');
                            _dialog.removeClass('visible');
                        }, function (response) {
                            //failed
                            var errorMessage = response.data ? response.data : "Unknown error, status code:" + response.status;
                            Notification.notify('Error', errorMessage, 4000);
                        });
                    });
                }
                function bind() {
                    app.log('modal bind');
                    scope.init({model: scope.clonedModel, localScope: scope});
                    _dialog = $compile(dialog)(scope);
                    var button = _dialog.find('#confirm');
                    $('input, textarea', _dialog).first().trigger('focus');
                    $(_dialog).keyup(function (event) {    //close on Esc
//                        app.log("Key pressed: ");
//                        app.log(event);
                        if (event.which == 27) closeDialog(button);
                    });
                    _dialog.find('#cancel').on('click', function () {
                        closeDialog(button);
                    });
                    element.on('click', function () {
                        app.log('modal element click');
                        bindConfirm(button);
                        //copy model into scope local var
                        scope.clonedModel = {};
                        scope.$apply(function(scope){
                            app._clone(scope.model, scope.clonedModel, false);
                            scope.init({model: scope.clonedModel, localScope: scope});
                        });
                        $(modal).appendTo('body');
                        $(_dialog).appendTo('body');
                        modal.addClass('visible');
                        _dialog.addClass('visible');
                    });
                    scope.$on('$destroy', function () {
                        modal.remove();
                        dialog.remove();
                    });
                }
            }
        }
    })

这是从 html 调用它的方式:

<div id="insert_constant" class="green_button small_button" template-id="constant_insert" style="float: left; position: relative;" model="const" confirm="onConstInsert(model, template)" init="initConstantDialog(model, localScope)" modal-dialog ng-transclude>Constants</div>

这是范围内的初始化函数:

$scope.initConstantDialog = function (model, localScope) {
        localScope.constants = $scope.constants;
        app.log("init constants dialog");
        app.log(model);
        app.log(localScope);
    }

常量包含这个:

[{"id":8,"name":"aa","oldName":"aa","value":"aa"},{"id":9,"name":"ee","oldName":"ee","value":"ee"}]

AngularJS v1.2.10

4

1 回答 1

0

经过一番调查,我在这里找到了问题的根源。

问题出在指令的 HTML 模板中,该模板作为隐藏的 DIV 元素存储在父 HTML 中。因此,当加载父控制器时,此 DIV 中的 ng-repeat 指令被编译并与父范围链接,并且此 DIV 的结果 html 动态更新为<!-- ngRepeat: c in constants -->. 后来,当我试图把这个DIV,编译并用作模板时,它已经不能用作模板了。

因此,解决方法是将此指令的模板移动到单独的 HTML 文件中。

于 2014-02-04T12:46:25.763 回答