我有一个控制器设置,其中包含一些要进行表单验证的函数。在这个控制器$ scope中,我有一个数组$ scope.errorMsgs,填充了用户填写表单时出现的错误消息字符串。
我还有一个显示此表单的指令。它们都连接到同一个模块。控制器和指令位于同一目录中的单独文件中。但是,指令的link函数中的作用域不引用控制器中的$ scope。事实上他们有不同的$ ID。关于为什么会发生这种情况的任何想法?
模块:
angular.module('aop.availabilitysolver', [
'aop.services',
'checklist-model'
]).run(['widgetService', function(widgetService) { 'use strict';
widgetService.registerWidgets([
{
title: 'AVAILABILITYSOLVER.WIDGETS.AVAILABILITYSOLVER',
translatableDescription: 'AVAILABILITYSOLVER.WIDGETS.AVAILABILITYSOLVER',
type: 'aop-availability-solver',
configuration: {},
width: 1
}
]);
}]);
控制器
angular.module('aop.availabilitysolver')
.controller('AvailabilitySolverController', ['$scope',
function ($scope) { 'use strict';
//console.log($scope);
$scope.selectGoalDropdown = ['Impressions', 'Spend'];
$scope.selectGoalTimespan = ['Day', 'Week', 'Month'];
$scope.selectGoals = [
{
id: '1',
name: 'Impressions'
},
{
id: '2',
name: 'Spend'
}
];
$scope.selectTimespan = [
{
id: '4',
name: 'Day'
},
{
id: '5',
name: 'Week'
},
{
id: '6',
name: 'Month'
}
];
$scope.selectedItem = 'test2';
$scope.selectedItem1 = 'test3';
$scope.per = [1, 2, 3, 4, 5, 6, 10, 12, 15, 20];
$scope.hours = [1, 3, 4, 12, 24, 36, 48, 72, 120, 168];
$scope.uncpd = ['uncapped'];
$scope.times = {
amt: [],
freq: [],
uncapped: []
};
$scope.caps = [];
$scope.quantity;
$scope.level = 'Fcap';
$scope.showErrors = false;
$scope.errorMsgs = [];
$scope.calculateFreqCaps = function(amt, freq, uncap) {
var rtn = [];
function isNothingSelected() { // No selections made
if(amt.length === 0 && freq.length === 0 && uncap.length === 0) {
rtn.push('Please choose frequency settings or select \'uncapped.\'');
$scope.errorMsgs.push('Please choose frequency settings or select \'uncapped.\'');
}
}
function malformedFrequencyOpts() { // Selected amount but no frequency & vice versa
if((amt.length > 0 && freq.length === 0) || (amt.length === 0 && freq.length > 0)) {
rtn.push('Please select both an amount and a frequency.');
$scope.errorMsgs.push('Please select both an amount and a frequency.');
}
}
function selectedTooMuch() { // Uncapped and frequency settings selected
if((amt.length > 0 || freq.length > 0) && uncap.length === 1) {
rtn.push('Choose uncapped only if no amount or frequency is selected');
$scope.errorMsgs.push('Choose uncapped only if no amount or frequency is selected');
}
}
isNothingSelected();
malformedFrequencyOpts();
selectedTooMuch();
if(rtn.length > 0) {
return rtn;
} else if (amt.length === 0 && freq.length === 0 && uncap.length === 1) { // Only uncapped selected
return ['uncapped'];
}
angular.forEach(amt, function (a) {
angular.forEach(freq, function (f) {
rtn.push(a + '/' + f + 'h');
});
});
return rtn;
};
$scope.validateSelectGoalQuantity = function(n) {
if(!Number(n)) {
$scope.errorMsgs.push('Quantity must be a number');
return false;
}
return true;
};
$scope.submitBtnClick = function() {
// Build Frequency cap JSON object
$scope.caps = $scope.calculateFreqCaps($scope.times.amt, $scope.times.freq, $scope.times.uncapped);
$scope.validateSelectGoalQuantity($scope.quantity);
if($scope.errorMsgs.length > 0) {
console.log($scope.errorMsgs);
// Show error message div and clear $scope.errorMsgs
$scope.showErrors = true;
//$scope.errorMsgs.length = 0;
}
else {
$scope.showErrors = false;
}
};
}]);
指令
angular.module('aop.availabilitysolver')
.directive('aopAvailabilitySolver', ['$filter', function($filter) { 'use strict';
return {
restrict: 'E',
link: function(scope, element, attrs) {
angular.noop(attrs);
// Hide error div initially
$('.availabilitySolverErrorDisplay').hide();
var i = element.find('.levelRadio :radio');
i.on('click', function() {
if($(i[0]).prop('checked')) {
scope.level = 'Fcap';
element.find('.freqCapDiv').show();
}
else {
scope.level = 'Bid';
element.find('.freqCapDiv').hide();
}
});
console.log(scope);
},
templateUrl: 'features/availabilitySolver/availabilitySolver.html'
};
}]);
HTML
<div ng-controller="AvailabilitySolverController">
<div class="container-fluid availabilitySolverScreen1">
<div class="row">
<div class="alert alert-danger availabilitySolverErrorDisplay">
</div>
</div>
<div class="row">
Campaign Selector
</div>
<!-- Goals -->
<div class="row">
<h5>Select Goal</h5>
<form name="selectGoalForm" novalidate>
<div class="col-md-4">
<button name="goals" class="btn btn-default" ng-model="selectedItem" ng-options="value.id as value.name for (key, value) in selectGoals" data-style="btn-primary" bs-select></button>
</div>
<div class="col-md-4">
<div class="col-md-10">
<input type="number" name="quantity" class="form-control" placeholder="Quantity" ng-model="quantity">
</div>
<div class="col-md-2">
per
</div>
</div>
<div class="col-md-4">
<button name="timespan" class="btn btn-default" ng-model="selectedItem1" ng-options="value.id as value.name for (key, value) in selectTimespan" data-style="btn-primary" bs-select></button>
</div>
</form>
</div><!-- End goals -->
<!-- Level cap -->
<div class="row">
<h5>Level</h5>
<div class="col-md-12">
<form class="levelRadio">
<input name="level" value="Fcap" type="radio" checked> Fcap
<input name="level" value="Bid" type="radio"> Bid
</form>
</div>
</div><!-- end level cap -->
<!-- Frequency cap analysis -->
<div class="row freqCapDiv">
<h5>Customize Frequency Cap for Analysis</h5>
<div class="col-md-8">
<!-- per -->
<div class="col-md-4">
<ul>
<li ng-repeat="item in per">
<input type="checkbox"
checklist-value="item"
checklist-model="times.amt" /> {{item}} per
</li>
</ul>
</div><!-- end per -->
<!-- hour(s) -->
<div class="col-md-4">
<ul>
<li ng-repeat="item in hours">
<input type="checkbox"
checklist-value="item"
checklist-model="times.freq" /> {{item}} hr
</li>
</ul>
</div>
<!-- uncapped -->
<div class="col-md-4">
<ul>
<li ng-repeat="item in uncpd">
<input type="checkbox"
checklist-value="item"
checklist-model="times.uncapped" /> uncapped
</ul>
</div>
</div>
<div class="col-md-4">
</div>
</div><!-- end frequency cap analysis -->
<!-- submit button -->
<div class="row">
<button class="btn btn-primary" ng-click="submitBtnClick()">Submit</button>
</div>
</div>
</div>