我有一个带有以下标记的主表单
<tabset vertical="true" type="pills">
<tab ng-repeat="tab in tabsViews" select="selectView(tab.name, tab.index)"
ng-show="tab.isVisible"
class=" {{tabsViews[tab.index-1]['invalid'] ? 'invalid-tab': 'valid-tab' }}">
<tab-heading>{{tab.title}}</tab-heading>
</tab>
</tabset>
并且我的控制器中的selectView方法如下:
$scope.previousIndex = null;
$scope.selectView = function (viewName, viewIndex) {
$scope.selections.showInvoicesDetailView = false;
$scope.selections.showInvoicesView = false;
$scope.selections.showPassesView = false;
if (viewIndex) {
if ($scope.previousIndex != null && $scope.form) {
$scope.tabsViews[$scope.previousIndex - 1]["invalid"] = $scope.form.$invalid;
}
$scope.previousIndex = viewIndex;
}
if (viewName.substring(0, 9) != 'invoices.')
$scope.selections.lastSelectedView = viewName;
else
$scope.selections.showInvoicesDetailView = true;
if (viewName == 'guestPasses')
$scope.selections.showPassesView = true;
if (viewName == 'invoices')
$scope.selections.showInvoicesView = true;
if ($scope.selections.isNew) {
window.console && console.log('SelectView called with the new.' + viewName + ' view...');
$state.go('new.' + viewName);
}
else {
window.console && console.log('SelectView called with the edit.' + viewName + ' view...');
$state.go('edit.' + viewName);
}
};
主窗体有一个指令来检测其脏状态并要求保存更改。问题是,当我在当前视图中更改任何内容时,该窗体的脏状态不会传播到该主窗体中。有没有办法根据特定的选项卡(定义为视图)脏状态设置主窗体脏状态?
为了更好地理解这个问题,这里是主要的表单标记(带标签的标记):
div ng-class="{'col-md-7': $parent.showSearch, 'col-md-11': !$parent.showSearch}">
@Html.Partial("_EditFormHeader")
<div class="fourpanel">
<div data-sm:collapse="$parent.showForm" id="hideFrm" class="pull-left col-sm-3 sm-search-list">
<form name="guestMainForm" novalidate role="form" data-sm:dirty-check data-server:error
ng-show="$parent.showForm && !selections.justDeleted" class="ng-cloak">
<div id="guestEditForm" class="widget" data-resize:container>
<div class="widget-head">
<div class="row">
<div class="clearfix"></div>
@Labels.guest: {{currentGuest.contactPerson.firstName + ' ' + currentGuest.contactPerson.lastName}} {{ !isNew ? '(' + currentGuest.guestNo + ')' : '' }}
<div class="pull-right text-right col-lg-1" style="padding-right:5px">
<i class="fa fa-angle-double-left sm-slider-button" ng-click="toggleFormVisibility()"
alt="@String.Format(Labels.hideX, Labels.account)" id="angle-left"></i>
</div>
</div>
</div>
<div class="widget-content">
<div class="scrollable widget-resize">
<div class="padd">
@Html.Partial("_EditFormAlerts")
</div>
<div class="col-lg-2 col-md-2 panel-container">
<tabset vertical="true" type="pills">
<tab ng-repeat="tab in tabsViews" select="selectView(tab.name, tab.index)"
ng-show="tab.isVisible"
class=" {{tabsViews[tab.index-1]['invalid'] ? 'invalid-tab': 'valid-tab' }}">
<tab-heading>{{tab.title}}</tab-heading>
</tab>
</tabset>
</div>
<div class="col-lg-8 col-md-4 panel-container">
<div data-ui-view data-autoscroll="false"></div>
<div data-ui-view="guestPasses" ng-show="selections.showPassesView"></div>
<div data-ui-view="invoices" data-autoscroll="false" ng-show="selections.showInvoicesView"></div>
</div>
</div>
</div>
<div class="widget-foot">
<div ng-show="!isNew">
<button class="btn btn-primary" ng-click="save(currentGuest)"
ng-disabled="form.$invalid || disableAction">
@Labels.save
</button>
<data-delete:button title="{{ '@Labels.delete: ' + currentGuest.contactPerson.firstName.trim() + ' ' + currentGuest.contactPerson.lastName.trim() + ' (' + currentGuest.guestNo +')' }}"
message="@String.Format(Messages.confirmDelete, Labels.guest)"
disable-action="disableAction"
delete="delete()">
</data-delete:button>
<data-cancel:button title="@Labels.unsavedChanges"
message="@Messages.unsavedChanges"
cancel="cancel()"
disable-action="disableAction"
dirty="form.$dirty">
</data-cancel:button>
</div>
<div ng-show="isNew">
<button id="btnAdd" class="btn btn-primary" ng-click="new(currentGuest)"
ng-disabled="form.$invalid || disableAction">
@Labels.add
</button>
<data-cancel:button title="@Labels.unsavedChanges"
message="@Messages.unsavedChanges"
cancel="cancel()"
disable-action="disableAction"
dirty="form.$dirty">
</data-cancel:button>
</div>
</div>
</div>
</form>
</div>
<div id="showFrm" class="sm-form-expand-button text-center col-sm-1"
ng-show="!$parent.showForm"
ng-click="toggleFormVisibility()">
<i class="fa fa-angle-double-right"></i>
<div class="panel2Label">@Labels.guest: {{ currentGuest.contact.firstName.trim() + ' ' + currentGuest.contact.lastName.trim() }} {{ !isNew ? '(' + currentGuest.guestNo + ')' : '' }}</div>
</div>
<div class="col-sm-5 panel-container">
<div data-ui-view="detail" data-autoscroll="true" ng-show="selections.showInvoicesDetailView"></div>
<div data-ui-view="passDetail"></div>
</div>
</div>
</div>
我创建了一个新指令并将其添加到我的视图表单中:
function ($modal, $rootScope, $location, $state) {
return {
restrict: 'A',
require: ['^form'],
//scope: {
// onOk: '&',
// onCancel: '&'
//},
link: function (scope, element, attrs, controllers) {
var form = controllers[0];
window.console && console.log(form);
window.onbeforeunload = function () {
if ((form && form.$dirty) || element.hasClass('ng-dirty')) {
// return resourceFactory.getResource('Messages', 'unsavedChanges');
if (scope.form)
{
scope.form.$setDirty();
}
}
};
}
};
我正在调试,我可以看到该表单已正确设置为我的视图表单,我可以使用表单访问父表单。$$ parentForm属性。但是,我不知道应该挂钩哪个事件来设置表单。$$ parentForm。$ setDirty当我的表单变脏时。如果你可以帮我解决这个问题,那我觉得它对我有用。
答案 0 :(得分:1)
引用来自表单指令的Angular文档:
在Angular中,表格可以嵌套。这意味着当所有子表单都有效时,外部表单也是有效的。但是,浏览器不允许嵌套元素,因此Angular提供的ngForm指令行为相同但可以嵌套。这允许您使用嵌套表单,这在使用ngRepeat指令动态生成的表单中使用Angular验证指令时非常有用。由于无法使用插值动态生成输入元素的name属性,因此必须在ngForm指令中包装每组重复输入,并将它们嵌套在外部表单元素中。
也许这也适用于$dirty
州,因此如果子表单为$dirty
,则父表单也将为$dirty
。我不确定在你的情况下你是否能够嵌套表格。我没有足够的背景来想象你想要达到的目标。
或者,当其中一个表单变脏时,您可以手动将主表单设置为脏。因为您添加了主表单中的代码,所以我可以看到您没有使用内置的脏检查器。也许你有充分的理由,但也许你并不知道它的存在。那么你必须使用angular form指令。 FormController
具有以下方法:$setDirty();
。