ng-options显示数据,而ng-repeat不显示

时间:2014-02-03 16:33:03

标签: angularjs angularjs-ng-repeat ng-options

我试图用AngularJS的ng-repeat指令显示一组数据。此html代码在同一个控制器下工作,并且constants变量更新为async:

具有相同的范围
 <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 stuff已经完成,在我看来它与我无关问题,所以我省略了所有这些代码。问题是 - 为什么ng-repeat不能与能够使用的数据ng-options一起使用?关于ng-repeat的特别之处是什么?有什么问题我需要知道吗?如果我用这个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

1 个答案:

答案 0 :(得分:0)

经过一番调查后,我发现了问题的根源。

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

因此,修复方法是在单独的HTML文件中移动此指令的模板。