我试图用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
答案 0 :(得分:0)
经过一番调查后,我发现了问题的根源。
问题出现在指令的HTML模板中,该模板作为隐藏的DIV元素存储在父HTML中。因此,当加载父控制器时,编译此DIV中的ng-repeat指令并将其与父范围链接,并将此DIV的结果html动态更新为<!-- ngRepeat: c in constants -->
。后来,当我尝试使用这个DIV,编译它并用作模板时,它已经无法用作模板。
因此,修复方法是在单独的HTML文件中移动此指令的模板。